2014-11-05 11 views
5

Durante alcuni test di carico di uno dei nostri servizi REST, si comincia a vedere questo tipo di registri per modello REST di primavera, quando il carico aumenta:modello Primavera RESTO accettare intestazioni

Sotto un carico concomitante e dopo 3-4 ore, l'intestazione Accept della richiesta http diventa

DEBUG: org.springframework.web.client.RestTemplate - Setting request Accept header to [text/plain, application/json, application/*+json, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain,<and so on>, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, <and so on>] 

alla fine tutti le chiamate a questo servizio utilizzando RestTemplate iniziare in mancanza con 400 errore (richiesta non valida)

il servizio REST chiamato accetta una stringa come input e ha la seguente firma

@RequestMapping(value = "/findRecordById", method = {RequestMethod.POST, RequestMethod.GET }) 
@ResponseBody 
public String findRecordById(@RequestBody String id) {//method body} 

Stiamo inviando tipo POST di richieste per questo servizio con richiesta di contenuto del modulo "QualcheID", per esempio "123"

Sotto carico leggero, non ci sono problemi nella chiamata del servizio.

Whats puzzling è il text/plain, */* che continua ad essere aggiunto all'elenco delle intestazioni di accettazione per il modello REST. Perché succede?

La dichiarazione modello chicco di REST è come questo:

<bean id="restTemplate" class="org.springframework.web.client.RestTemplate"> 
     <constructor-arg> 
      <bean class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory"> 
       <property name="readTimeout"> 
        <value>90000</value> 
       </property> 
       <property name="httpClient" ref="restHttpClient" /> 
      </bean> 
     </constructor-arg> 
    </bean> 

    <bean id="restHttpClient" class="org.apache.http.impl.client.DefaultHttpClient"> 
      <constructor-arg> 
      <bean class="org.apache.http.impl.conn.PoolingClientConnectionManager"> 
       <property name="defaultMaxPerRoute"> 
        <value>100000</value> 
       </property> 
       <property name="maxTotal"> 
        <value>100000</value> 
       </property>     

      </bean> 
      </constructor-arg> 
    </bean> 

Come si crea la richiesta:

String postParams = "\"" + id + "\""; 

String postResp = restTemplate.postForObject("findRecordById",postParams, String.class); 
+1

prego ci mostra un esempio di una richiesta si effettua con il 'RestTemplate' .. –

+0

curato la questione per mostrare come un richiesta effettuata –

+0

Quindi ottieni 'restTemplate' direttamente da' ApplicationContext' senza ulteriori modifiche? E invii tonnellate di richieste come sopra? –

risposta

0

La prego di provare questo:

restTemplate.getMessageConverters().add(new StringHttpMessageConverter()); 

String postParams = "\"" + id + "\""; 

String postResp = restTemplate.postForObject("findRecordById",postParams, String.class); 
+0

Vedo che il costruttore aggiunge già questo convertitore di messaggi. Non sembra che questo potrebbe essere la causa del problema. –

0

text/plain viene aggiunto perché si tenta di leggere una stringa e il RestTemplate, trovato StringHttpMessageConverter come convertitore per la propria r equest e il tipo di supporto supportato per StringHttpMessageConverter è text/plain.

Come si può vedere in questo metodo di RestTemplate.

public void doWithRequest(ClientHttpRequest request) throws IOException { 
      if (responseType != null) { 
       List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>(); 
       for (HttpMessageConverter<?> messageConverter : getMessageConverters()) { 
        if (messageConverter.canRead(responseType, null)) { 
         List<MediaType> supportedMediaTypes = messageConverter.getSupportedMediaTypes(); 
         for (MediaType supportedMediaType : supportedMediaTypes) { 
          if (supportedMediaType.getCharSet() != null) { 
           supportedMediaType = 
             new MediaType(supportedMediaType.getType(), supportedMediaType.getSubtype()); 
          } 
          allSupportedMediaTypes.add(supportedMediaType); 
         } 
        } 
       } 
       if (!allSupportedMediaTypes.isEmpty()) { 
        MediaType.sortBySpecificity(allSupportedMediaTypes); 
        if (logger.isDebugEnabled()) { 
         logger.debug("Setting request Accept header to " + allSupportedMediaTypes); 
        } 
        request.getHeaders().setAccept(allSupportedMediaTypes); 
       } 
      } 
     } 
    } 
1

Nel caso in cui qualcuno viene qui a causa del testo ripetuto/plain Accetta problema intestazione che il manifesto ha avuto, ho sperimentato la stessa cosa ed ecco quello che stava accadendo: Abbiamo avuto la nostra definizione di fagioli al solito per il modello riposo in servlet-context.xml in cui abbiamo specificato un convertitore messaggio per application/json in questo modo (questo è per la primavera-fagioli 4.0):

<beans:bean id="myRestTemplate" class="com.mypackage.MyClass"> 
     <beans:property name="requestFactoryNonSSL" ref="restTemplateNonSSLRequestFactory"/> 
     <beans:property name="requestFactorySSL" ref="restTemplateNonSSLRequestFactory"/> 
     <beans:property name="messageConverters"> 
      <beans:list> 
       <beans:bean class="org.springframework.http.converter.StringHttpMessageConverter"> 
        <beans:property name="supportedMediaTypes"> 
         <beans:list> 
          <beans:value>application/json;charset=UTF-8</beans:value> 
         </beans:list> 
        </beans:property> 
       </beans:bean>   
      </beans:list> 
     </beans:property> 
    </beans:bean> 

Tuttavia nel nel codice sorgente siamo anche stati aggiungendo esplicitamente uno StringHttpMessageConverter utilizzando:

restTemplate.getMessageConverters().add(new StringHttpMessageConverter()); 

Tuttavia, questo elenco di messageConverter richiedeva solo una nuova istanza di StringHttpMessageConverter aggiunta ad ogni richiesta. Per ogni richiesta Spring passa attraverso la lista dei convertitori di messaggi e aggiunge l'intestazione Accept corrispondente (text/plain). Dopo così tante richieste, la lunghezza dell'intestazione aumenta così tanto da essere respinta dal contenitore del server che stai chiamando. Il modo più semplice per risolvere questo problema era quello di specificare il testo/plain come un SupportMediaTypes nel servlet-context.xml e rimuovere la riga sopra nel codice. Se non è possibile fare ciò è necessario inserire un codice di controllo per assicurarsi che StringHttpMessageConverter non venga ripetutamente aggiunto all'istanza restTemplate.

Ecco il servlet-context.xml con il testo/plain supportedMediaType aggiunto:

<beans:bean id="myRestTemplate" class="com.mypackage.MyClass"> 
     <beans:property name="requestFactoryNonSSL" ref="restTemplateNonSSLRequestFactory"/> 
     <beans:property name="requestFactorySSL" ref="restTemplateNonSSLRequestFactory"/> 
     <beans:property name="messageConverters"> 
      <beans:list> 
       <beans:bean class="org.springframework.http.converter.StringHttpMessageConverter"> 
        <beans:property name="supportedMediaTypes"> 
         <beans:list> 
          <beans:value>application/json;charset=UTF-8</beans:value> 
          <beans:value>text/plain</beans:value> 
         </beans:list> 
        </beans:property> 
       </beans:bean>   
      </beans:list> 
     </beans:property> 
    </beans:bean> 
Problemi correlati