0

I have a command line java utility which needs to make a rest call to jersey rest service.

@POST    
@Path("/{name}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response insert(@PathParam("name") String nestName,
                           @QueryParam("id") String id,
                           @FormDataParam("file") InputStream fileStream,
                           @FormDataParam("file") FormDataContentDisposition fileDetail) throws IOException {}

And making a request through java command line utility like this:

Map<String,String> headers = new HashMap<String,String>();
headers.put(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA + "; boundary=--------------------------458269817398405552698839");
headers.put(HttpHeaders.ACCEPT, "*/*");
headers.put(HttpHeaders.CACHE_CONTROL, "no-cache");
headers.put(HttpHeaders.ACCEPT_ENCODING, "gzip, deflate");

URLConnection conn = url.openConnection();
if(headers!=null && !headers.isEmpty()) {
    for(Map.Entry<String, String> entry: headers.entrySet()) {
        conn.setRequestProperty(entry.getKey(),entry.getValue());
    }
}

ServiceHttpResponse response = new ServiceHttpResponse(con.getResponseCode(), con.getResponseMessage());

I get following exception. Is there some other way to set mime type?

javax.ws.rs.BadRequestException: HTTP 400 Bad Request

at org.glassfish.jersey.media.multipart.internal.MultiPartReaderClientSide.readFrom(MultiPartReaderClientSide.java:188) at org.glassfish.jersey.media.multipart.internal.MultiPartReaderClientSide.readFrom(MultiPartReaderClientSide.java:93) at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:256) at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:235) at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:155) at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundReadFrom(MappableExceptionWrapperInterceptor.java:74) at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:155) at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1085) at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:874) at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:808) at org.glassfish.jersey.server.ContainerRequest.readEntity(ContainerRequest.java:234) at org.glassfish.jersey.media.multipart.internal.FormDataParamValueFactoryProvider$ValueFactory.getEntity(FormDataParamValueFactoryProvider.java:126) at org.glassfish.jersey.media.multipart.internal.FormDataParamValueFactoryProvider$FormDataParamValueFactory.provide(FormDataParamValueFactoryProvider.java:280) at org.glassfish.jersey.server.spi.internal.ParamValueFactoryWithSource.provide(ParamValueFactoryWithSource.java:71) at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:90)

at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:127) at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160)

at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)

at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)

at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)

at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)

at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)

at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)

at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)

at org.glassfish.jersey.internal.Errors.process(Errors.java:315)

at org.glassfish.jersey.internal.Errors.process(Errors.java:297) at org.glassfish.jersey.internal.Errors.process(Errors.java:267)

at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)

at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)

at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473) at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)

at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)

at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)

at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)

at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808)

at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)

at com.cadence.adw.common.generic.xml.server.service.http.RequestInterceptor.doFilter(RequestInterceptor.java:95)

at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)

at org.eclipse.jetty.servlets.UserAgentFilter.doFilter(UserAgentFilter.java:83) at org.eclipse.jetty.servlets.GzipFilter.doFilter(GzipFilter.java:300)

at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)

at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)

at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)

at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)

at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)

at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)

at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)

at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)

at org.eclipse.jetty.server.Server.handle(Server.java:497)

at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)

at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)

at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)

at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)

at java.lang.Thread.run(Thread.java:748)

Caused by: org.jvnet.mimepull.MIMEParsingException: Missing start boundary

at org.jvnet.mimepull.MIMEParser.skipPreamble(MIMEParser.java:318)

at org.jvnet.mimepull.MIMEParser.access$300(MIMEParser.java:68)

at org.jvnet.mimepull.MIMEParser$MIMEEventIterator.next(MIMEParser.java:154)

at org.jvnet.mimepull.MIMEParser$MIMEEventIterator.next(MIMEParser.java:132)

at org.jvnet.mimepull.MIMEMessage.makeProgress(MIMEMessage.java:228) at org.jvnet.mimepull.MIMEMessage.parseAll(MIMEMessage.java:189)

at org.jvnet.mimepull.MIMEMessage.getAttachments(MIMEMessage.java:115)

at org.glassfish.jersey.media.multipart.internal.MultiPartReaderClientSide.getMimeParts(MultiPartReaderClientSide.java:272)

at org.glassfish.jersey.media.multipart.internal.MultiPartReaderClientSide.readMultiPart(MultiPartReaderClientSide.java:231)

at org.glassfish.jersey.media.multipart.internal.MultiPartReaderServerSide.readMultiPart(MultiPartReaderServerSide.java:91)

at org.glassfish.jersey.media.multipart.internal.MultiPartReaderClientSide.readFrom(MultiPartReaderClientSide.java:183)

... 58 more

tryingToLearn
  • 10,691
  • 12
  • 80
  • 114

1 Answers1

2

Setting the request params is not the correct way to send a multipart request. Just setting the content-type with a boundary is not enough. That boundary is used inside the body of the request to separate different "parts" of the request and also to end the body. For example

Content-Type: multipart/form-data; boundary=AaB03x

--AaB03x
Content-Disposition: form-data; name="submit-name"

Larry
--AaB03x
Content-Disposition: form-data; name="files"; filename="file1.txt"
Content-Type: text/plain

... contents of file1.txt ...
--AaB03x--

UrlConnection (or HttpUrlConnection) doesn't have any API to easily send Multipart requests. You would need to manually create this request body and sending out via the output stream of the connection.

The purpose of multipart is to send multiple parameters where some parameters are binary objects like image files and such. If all the parameters are only text, you can use application/x-www-form-urlencoded content-type. This is what setting the request parameters on the HttpUrlConnection does when you make a POST request. Then on the server, you would use @FormParam("param-name") instead of @FormDataParam. It would be @QueryParam if you are making a GET request.

If what you want is to make a Multipart request, you should look into a client that supports sending one instead of having to manually construct the correct body format manually. You can look into Jersey Client and its Multipart support. There are many other client libraries out there also. Just do some searching.

Also

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720