Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload a text File from .Net http client to Java REST API in InputStream format

I have a case where I want to upload a text File from .Net http client to Java REST API in InputStream format. When I hit the Java REST from Postman with File in Form-Data Body, the file is getting received in Java REST service perfectly fine. When I try is same thing from the .Net Client, i have getting some exceptions as below.

My .Net HTTP Client code is as below,

var client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:8082/processes/view/createDocumentfromFile/851");
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("procId", "100");
client.DefaultRequestHeaders.Add("DocName", "ProphetWorkflow");
var content = new MultipartFormDataContent();
content.Add(new ByteArrayContent(File.ReadAllBytes(@"C:\Users\charan.ghate\Desktop\Calculation.txt")));
HttpResponseMessage messge = client.PostAsync(client.BaseAddress, content).Result;
if (messge.IsSuccessStatusCode)
{
    string result = messge.Content.ReadAsStringAsync().Result;
    lblResponse.Text = result;
}

My Java REST Service Code is as below,

@POST
@Path("/createDocumentfromFile/{procId}")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN })
@Produces({ MediaType.APPLICATION_JSON })
public Response createDocumentfromFile(@PathParam("procId") Long piOID, @HeaderParam("DocName") String modulename,
        @Context HttpServletRequest request, @Context HttpServletResponse response,
        @FormDataParam("file") InputStream uploadedInputStream) {
//
//Operation on the input stream
//
}

When I hit a REST API, I have getting the exception at both the side in .Net as well as In Java, detailed below

.Net Error Message:

StatusCode: 500, ReasonPhrase: 'Internal Server Error', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Connection: close
  Date: Fri, 23 Dec 2016 15:08:03 GMT
  Server: Apache-Coyote/1.

Java exception:

    Dec 23, 2016 8:38:03 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [cxf-jaxrs-servlet] in context with path [/ipp-portal] threw exception [Servlet execution threw an exception] with root cause
java.lang.NoSuchMethodError: javax.ws.rs.ClientErrorException.validate(Ljavax/ws/rs/core/Response;Ljavax/ws/rs/core/Response$Status$Family;)Ljavax/ws/rs/core/Response;
    at javax.ws.rs.ClientErrorException.<init>(ClientErrorException.java:88)
    at org.apache.cxf.jaxrs.utils.JAXRSUtils.findTargetMethod(JAXRSUtils.java:503)
    at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:198)
    at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:90)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:239)
    at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:248)
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:222)
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:153)
    at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:167)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:286)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:206)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:262)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.eclipse.stardust.ui.web.html5.EnhancedJarResourceFilter.doFilter(EnhancedJarResourceFilter.java:140)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at com.icesoft.faces.webapp.http.servlet.TouchSessionFilter.doFilter(TouchSessionFilter.java:77)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:436)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

Could you please suggest me the best way to transfer a file from .Net Client to Java REST Service.

like image 566
Smita Koparkar Avatar asked Dec 23 '16 15:12

Smita Koparkar


2 Answers

The exception

java.lang.NoSuchMethodError: javax.ws.rs.ClientErrorException.validate(Ljavax/ws/rs/core/Response;Ljavax/ws/rs/core/Response$Status$Family;)Ljavax/ws/rs/core/Response;

means that it tries to get a method at runtime of type Response validate(final Response response, Response.Status.Family expectedStatusFamily) from the class ClientErrorException that it cannot find.

This generally happens when you build your application with one version of your library and you run it against a different version that is not compatible.

Knowing that this method has been added since JAX-RS 2.0, I believe that you compiled your code with JAX-RS 2.0 or higher and you have a version 1.x in your classpath that is used instead at Runtime. Check the classpath used at Runtime and ensure that you have only the same version of the JAX-RS that you used at Compile time.

like image 125
Nicolas Filotto Avatar answered Oct 19 '22 23:10

Nicolas Filotto


What is probably happening is that the server does not like the request, prepare to send an error, and fails because of a library mismatch (as pointed by Nicolas Filotto). This is why you are seeing a generic HTTP 500 error instead of some (more informative) 4XX.

Resolve the library version mismatch is probably a good idea, even if it works when the request matches what the server expects (as showed with Postman)

Looking at the signatures on both sides, this is what I could think of :

  • add MediaType.MULTIPART_FORM_DATA_TYPE to the consumed content types.

  • remove client.DefaultRequestHeaders.Add("procId", "100");, as the procId is expected on the path, not in the headers.

  • add file as name of the ByteArrayContent :

    content.Add(new ByteArrayContent(File.ReadAllBytes(@"C:\Users\charan.ghate\Desktop\Calculation.txt")), "file");
    

Additionally you can try to disable the Expect: 100-continue header used by default by the .NET HttpClient, some servers don't handle it.

client.DefaultRequestHeaders.ExpectContinue = false;
like image 45
bwt Avatar answered Oct 19 '22 23:10

bwt