2017-06-07 2 views
0

J'ai un service de repos qui utilise componenet sous-jacent. J'utilise wildfly et wildfly patch 4.7.0 (apache chameau 2.19)Apache camel Service de repos avec des lettres de fond et nordiques

J'ai un problème pour répondre avec des lettres nordiques de mon service de repos. Testé avec un facteur.

Le code est:

@Override 
    public void configure() throws Exception { 
     restConfiguration().component("undertow"); 
     rest("/hello").post("/{name}").consumes("application/json").to("direct:testpost"); 
     from("direct:testpost") 
       .routeId("testpost") 
       .log("${body}") 
       .transform().jsonpath("test"); 
    } 

Et quand j'envoyer:

POST /hello/Anton HTTP/1.1 Host: 192.168.56.103:8080 Content-Type: application/json ; charset=UTF-8 Cache-Control: no-cache Postman-Token: c7ed9034-8b58-d104-9804-a1ff60a26f65

{"test": "test with Å"}

Je reçois l'erreur:

2017-06-07 07:06:16,253 INFO [testput] (default task-5) {"test": "test with Å"}

2017-06-07 07:06:16,258 ERROR [io.undertow.request] (default task-5) UT005071: Undertow request failed HttpServerExchange{ POST /hello/Anton request {Accept=[/], Postman-Token=[a3f9c986-e6d1-1f41-e4f8-54f3e38678c3], Accept-Language=[sv-SE,sv;q=0.8,en-US;q=0.6,en;q=0.4], Cache-Control=[no-cache], Accept-Encoding=[gzip, deflate], Origin=[chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop], User-Agent=[Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36], Connection=[keep-alive], Content-Length=[24], Content-Type=[application/json ; charset=UTF-8], Host=[192.168.56.103:8080]} response {Accept=[/], Postman-Token=[a3f9c986-e6d1-1f41-e4f8-54f3e38678c3], Accept-Language=[sv-SE,sv;q=0.8,en-US;q=0.6,en;q=0.4], name=[Anton], X-Powered-By=[Undertow/1], Accept-Encoding=[gzip, deflate], breadcrumbId=[ID-localhost-39384-1496833334654-11-5], Server=[WildFly/10], Origin=[chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop], User-Agent=[Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36], Content-Type=[application/json ; charset=UTF-8]}}: org.apache.camel.TypeConversionException: Error during type conversion from type: java.lang.String to the required type: java.nio.ByteBuffer with value test with Å due java.nio.BufferOverflowException at org.apache.camel.impl.converter.BaseTypeConverterRegistry.createTypeConversionException(BaseTypeConverterRegistry.java:629) at org.apache.camel.impl.converter.BaseTypeConverterRegistry.convertTo(BaseTypeConverterRegistry.java:150) at org.apache.camel.impl.converter.BaseTypeConverterRegistry.convertTo(BaseTypeConverterRegistry.java:121) at org.apache.camel.component.undertow.UndertowConsumer.handleRequest(UndertowConsumer.java:135) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202) at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:805) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:748) Caused by: org.apache.camel.RuntimeCamelException: java.nio.BufferOverflowException at org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1756) at org.apache.camel.util.ObjectHelper.invokeMethod(ObjectHelper.java:1355) at org.apache.camel.impl.converter.StaticMethodTypeConverter.convertTo(StaticMethodTypeConverter.java:59) at org.apache.camel.impl.converter.BaseTypeConverterRegistry.doConvertTo(BaseTypeConverterRegistry.java:306) at org.apache.camel.impl.converter.BaseTypeConverterRegistry.convertTo(BaseTypeConverterRegistry.java:133) ... 7 more Caused by: java.nio.BufferOverflowException at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:189) at java.nio.ByteBuffer.put(ByteBuffer.java:859) at org.apache.camel.converter.NIOConverter.toByteBuffer(NIOConverter.java:102) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.camel.util.ObjectHelper.invokeMethod(ObjectHelper.java:1351) ... 10 more

configuration undertow:

<subsystem xmlns="urn:jboss:domain:undertow:3.1"> 
      <buffer-cache name="default"/> 
      <server name="default-server"> 
       <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/> 
       <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/> 
       <host name="default-host" alias="localhost"> 
        <location name="/" handler="welcome-content"/> 
        <filter-ref name="server-header"/> 
        <filter-ref name="x-powered-by-header"/> 
       </host> 
      </server> 
      <servlet-container name="default"> 
       <jsp-config/> 
       <websockets/> 
      </servlet-container> 
      <handlers> 
       <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/> 
      </handlers> 
      <filters> 
       <response-header name="server-header" header-name="Server" header-value="WildFly/10"/> 
       <response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow/1"/> 
      </filters> 
     </subsystem> 

Alors, avez-vous des idées pour résoudre ce problème? Toute aide est appréciée!

+0

est-ce que c'est le wildfly intérieur ou le ressac autonome? si dans wildfly, s'il vous plaît poster sous-système config sous-système, si autonome poste code d'installation – ctomc

+0

Ceci est à l'intérieur de la wildfly. quand j'ajoute la ligne .convertBodyTo (byte []. class); après la transformation, le code fonctionne bien. Peut-être quelque chose à faire avec l'encodage ?? Je construis le code avec utf8. – anpt

Répondre

0

C'est un bogue dans org.apache.camel.converter.NIOConverter (2.18.4)

public static ByteBuffer toByteBuffer(String value, Exchange exchange) { 
    ByteBuffer buf = ByteBuffer.allocate(value.length()); 
    byte[] bytes = null; 
    if (exchange != null) { 
     String charsetName = exchange.getProperty(Exchange.CHARSET_NAME, String.class); 
     if (charsetName != null) { 
      try { 
       bytes = value.getBytes(charsetName); 
      } catch (UnsupportedEncodingException e) { 
       LOG.warn("Cannot convert the byte to String with the charset " + charsetName, e); 
      } 
     } 
    } 
    if (bytes == null) { 
     bytes = value.getBytes(); 
    } 
    buf.put(bytes); 
    buf.flip(); 
    return buf; 
} 

Le ByteBuffer est alloué avec String.length() sans tenir compte du fait qu'il peut contenir des caractères à deux octets. Je contourne ce bogue en remplaçant le convertisseur dans le registre en utilisant un eventlistener.

void onContextStarting(@Observes CamelContextStartingEvent event) { 
    def context = event.getContext(); 
    def registry = context.getTypeConverterRegistry(); 

    registry.setTypeConverterExistsLoggingLevel(LoggingLevel.INFO) 
    registry.setTypeConverterExists(TypeConverterExists.Override) 
    registry.addTypeConverter(ByteBuffer.class,String.class, new StringToByteBufferConverter()); 
    registry.setTypeConverterExists(TypeConverterExists.Ignore) 
} 

Le convertisseur je l'ai remplacé avec utilise le byte.length d'affecter le ByteBuffer de sorte que le tampon correspond au nombre d'octets pour actualy la chaîne:

import org.apache.camel.Exchange; 
import org.apache.camel.support.TypeConverterSupport; 

import java.io.UnsupportedEncodingException; 
import java.nio.ByteBuffer; 

public class StringToByteBufferConverter extends TypeConverterSupport { 

    public <T> T convertTo(Class<T> type, Exchange exchange, Object object) { 
    String value = (String)object; 
    byte[] bytes = null; 
    if (exchange != null) { 
     String charsetName = exchange.getProperty(Exchange.CHARSET_NAME, String.class); 
     if (charsetName != null) { 
      try { 
       bytes = value.getBytes(charsetName); 
      } catch (UnsupportedEncodingException e) { 
       throw new UnsupportedOperationException(e); 
      } 
     } 
    } 
    if (bytes == null) { 
     bytes = value.getBytes(); 
    } 
    ByteBuffer buf = ByteBuffer.allocate(bytes.length); 
    buf.put(bytes); 
    buf.flip(); 
    return (T)buf; 
    } 

} 

Vous pouvez également contourner ce bug en convertissant le corps à un type autre que String pour contourner le mauvais convertisseur:

@Override 
public void configure() throws Exception { 
    restConfiguration().component("undertow"); 
    rest("/hello").post("/{name}").consumes("application/json").to("direct:testpost"); 
    from("direct:testpost") 
      .routeId("testpost") 
      .log("${body}") 
      .transform().jsonpath("test") 
      .convertBodyTo(byte[].class); 
} 
+0

Le commit https://github.com/apache/camel/commit/4b06e5fe5f0d4e4eba1de9c5f10eb65ef5b6bf74 corrige le bug. – anpt