2016-07-14 7 views
2

Ich bin neu in Camel und ich habe ein Problem beim Senden von Dateien zum Webservice über Kamel http.
Ich habe einen Rest-Webdienst, der Multipart-Formulardatentypinhalt verbraucht und Eingabe als Teil von Formulardaten akzeptiert. es gibt mir die folgenden Fehler auf Kamel-Konsole Wenn ich Datei und Formular-Parameter über Kamel senden:Kann nicht Datei zum Rest Webservice über Apache Kamel http senden

Stacktrace 
--------------------------------------------------------------------------------------------------------------------------------------- 
org.apache.camel.component.http.HttpOperationFailedException: HTTP operation failed invoking http://localhost:8080/JAX_RS_Application/resource/restwb/upload with statusCode: 415 
    at org.apache.camel.component.http.HttpProducer.populateHttpOperationFailedException(HttpProducer.java:230) 
    at org.apache.camel.component.http.HttpProducer.process(HttpProducer.java:156) 
    at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61) 
    at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:129) 
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77) 
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:448) 
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191) 
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:118) 
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:80) 
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191) 
    at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:435) 
    at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:211) 
    at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:175) 
    at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:174) 
    at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:101) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:745) 

Der Fehler i auf der Serverseite Konsole ist wie folgt:

SEVERE: MessageBodyReader not found for media type=application/octet-stream, typ 
e=class org.glassfish.jersey.media.multipart.FormDataMultiPart, genericType=clas 
s org.glassfish.jersey.media.multipart.FormDataMultiPart. 

Der Code-Schnipsel der Web-Service-Erholung über Jersey erstellt ist wie folgt:

import java.io.IOException; 
import java.io.InputStream; 

import javax.ws.rs.*; 
import javax.ws.rs.core.MediaType; 

import org.apache.commons.io.IOUtils; 
import org.glassfish.jersey.media.multipart.FormDataContentDisposition; 
import org.glassfish.jersey.media.multipart.FormDataParam; 

@Path("/restwb") 
public class FileResource { 
    @POST 
    @Path("/upload") 
    @Consumes(MediaType.MULTIPART_FORM_DATA) 
    public String uploadFile(@FormDataParam("username") String username,@FormDataParam("password") String password,@FormDataParam("upload") InputStream is) { 
      String output ="Hi "+username+" your password is "+password; 
      output=output+IOUtils.LINE_SEPARATOR +IOUtils.LINE_SEPARATOR; 
      output=output+"Output :"+IOUtils.LINE_SEPARATOR+"------------------------------------------------------------------------------"+IOUtils.LINE_SEPARATOR; 
      try { 
       output=output+IOUtils.toString(is)+IOUtils.LINE_SEPARATOR+IOUtils.LINE_SEPARATOR; 
       output=output+"==================================================================================================="+IOUtils.LINE_SEPARATOR+IOUtils.LINE_SEPARATOR; 
       System.out.println("Output :"+output); 
      } catch (Exception e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      return output; 
    } 
} 

Und mein Kamel Config ist wie folgt:

import org.apache.camel.*; 
import org.apache.camel.builder.RouteBuilder; 
import org.apache.camel.impl.DefaultCamelContext; 
import org.apache.camel.spi.Synchronization; 
import org.apache.camel.spi.UnitOfWork; 
import org.apache.http.HttpEntity; 
import org.apache.http.entity.ContentType; 
import org.apache.http.entity.mime.HttpMultipartMode; 
import org.apache.http.entity.mime.MultipartEntityBuilder; 
import org.apache.http.entity.mime.content.FileBody; 
import org.apache.http.entity.mime.content.StringBody; 
import org.apache.james.mime4j.message.Multipart; 
import org.apache.log4j.Logger; 

import java.io.File; 
import java.io.InputStream; 
import java.util.List; 
import java.util.Map; 

/** 
* Created by Manish.Pillai on 7/16/2015. 
*/ 
public class LoggingMain { 

    private static final Logger logger =Logger.getLogger(LoggingMain.class); 

    public static void main(String[] args) throws Exception{ 
     CamelContext camelContext =new DefaultCamelContext(); 
     try { 
      camelContext.addRoutes(new RouteBuilder() { 
       @Override 
       public void configure() throws Exception { 
        from("file:C:\\temp?delay=5000&move=processed&moveFailed=error&antExclude=**/processed/**,**/error/**") 
          .process(new Processor() { 
           public void process(Exchange exchange) throws Exception { 
            exchange.getContext().getTypeConverterRegistry().addTypeConverter(HttpEntity.class,InputStream.class,new InputStreamToHttpEntityConvertor()); 
            exchange.getOut().setBody(exchange.getIn().getBody(),HttpEntity.class); 
           } 
          }) 
          .to("http://localhost:8080/JAX_RS_Application/resource/restwb/upload"); 
       } 
      }); 

      camelContext.getRestConfiguration(); 
      camelContext.start(); 
      Thread.sleep(5000); 
      camelContext.stop(); 

     } catch (Exception e) { 
      logger.error(e.getMessage()); 
     } 
    } 

    static class InputStreamToHttpEntityConvertor implements TypeConverter { 

     public boolean allowNull() { 
      return false; 
     } 

     public <T> T convertTo(Class<T> type, Object value) throws TypeConversionException { 
      Exchange exchange=(Exchange)value; 

      StringBody username = new StringBody("username", ContentType.MULTIPART_FORM_DATA); 
      StringBody password = new StringBody("password", ContentType.MULTIPART_FORM_DATA); 
      MultipartEntityBuilder multipartEntityBuilder=MultipartEntityBuilder.create(); 
      multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); 
      multipartEntityBuilder.addPart("upload", new FileBody(exchange.getIn().getBody(File.class), ContentType.MULTIPART_FORM_DATA, (String) exchange.getIn().getHeader(Exchange.FILE_NAME))); 
      multipartEntityBuilder.addPart("username",username); 
      multipartEntityBuilder.addPart("password",password); 
      return (T)multipartEntityBuilder.build(); 
     } 

     public <T> T convertTo(Class<T> aClass, Exchange exchange, Object o) throws TypeConversionException { 
      return convertTo(aClass,o); 
     } 

     public <T> T mandatoryConvertTo(Class<T> type, Object value) throws TypeConversionException, NoTypeConversionAvailableException { 
      return convertTo(type,value); 
     } 

     public <T> T mandatoryConvertTo(Class<T> type, Exchange exchange, Object value) throws TypeConversionException, NoTypeConversionAvailableException { 
      return convertTo(type,value); 
     } 

     public <T> T tryConvertTo(Class<T> type, Object value) { 
      return convertTo(type,value); 
     } 

     public <T> T tryConvertTo(Class<T> type, Exchange exchange, Object value) { 
      return convertTo(type,value); 
     } 
    } 

} 

Alle Kabel sind hilfreich.

+0

Bevor Sie Camel verwenden, haben Sie tatsächlich versucht, es mit einem Rest-Tool oder SOAPUI oder ähnlichem zu senden, um zu überprüfen, ob alles funktioniert? –

+0

Ja .. Ich habe Postboten verwendet, um den Dienst zu testen, es funktioniert gut. – madmax1540

Antwort

0

Nun, es gibt einige Dinge, die in Ihrem Code verbessert werden können.

Erstens, da Sie einen MultipartEntityBuilder verwenden, bedeutet das, dass Sie Apache HttpClient Version 4.3+ verwenden, so dass Sie für die beste Kompatibilität Camel's HTTP4 component verwenden sollten.

Drittens in einem Beispiel so klein wie diese, Sie verwenden müssen, um den Konverter nicht wirklich, können Sie etwas tun:

public class LoggingMain { 

    private static final Logger logger = Logger.getLogger(LoggingMain.class); 

    public static void main(String[] args) throws Exception { 
     CamelContext camelContext = new DefaultCamelContext(); 
     try { 
      camelContext.addRoutes(new RouteBuilder() { 
       @Override 
       public void configure() throws Exception { 
        from("file:C:\\temp?delay=5000&move=processed&moveFailed=error&antExclude=**/processed/**,**/error/**") 
          .process(new Processor() { 
           public void process(Exchange exchange) throws Exception { 
            StringBody username = new StringBody("username", ContentType.MULTIPART_FORM_DATA); 
            StringBody password = new StringBody("password", ContentType.MULTIPART_FORM_DATA); 

            MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create(); 
            multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); 
            multipartEntityBuilder.addPart("username", username); 
            multipartEntityBuilder.addPart("password", password); 

            String filename = (String) exchange.getIn().getHeader(Exchange.FILE_NAME); 
            File file = exchange.getIn().getBody(File.class); 
            multipartEntityBuilder.addPart("upload", new FileBody(file, ContentType.MULTIPART_FORM_DATA, filename)); 

            exchange.getIn().setBody(multipartEntityBuilder.build()); 
           } 
          }) 
          .to("http4://localhost:8080/JAX_RS_Application/resource/restwb/upload"); 
       } 
      }); 

      camelContext.getRestConfiguration(); 
      camelContext.start(); 
      Thread.sleep(5000); 
      camelContext.stop(); 

     } catch (Exception e) { 
      logger.error(e.getMessage()); 
     } 
    } 

} 

Ich hoffe, das hilft!

+0

Vielen Dank für Ihre Antwort !!! Ich habe bereits versucht, den Inhaltstyp auf multipart/form-data zu setzen es gibt mir 400 Fehler ... Zweitens gibt das Setzen von Körper zu HttpEntity gibt mir einen Fehler, der sagt .. Kein Konverter gefunden für MultipartFormEntity zu InputStream daher muss ich einen Konverter erstellen .... Und ja, ich stimme Ihnen zu, dass httpclient builder am besten mit http4 unterstützt wird es ausprobieren .... – madmax1540

+0

Die Probe, die ich gab funktioniert gut für mich, können Sie es für sich selbst ausprobieren: https://github.com/FingolfinTEK/camel-http4-jersey-upload-test –

+0

Und das Festlegen des Inhaltstyps auf multipart/form-data ist ein Muss, da Ihr Dienst nur diesen Typ verwendet, jeder andere würde zu einem Fehler führen. Obwohl du Multipart-Objekte verwendest, kann ich davon ausgehen, dass sie weggelassen werden können. –