Grails JAX-RS REST multipart file upload - spring

Trying to get a multipart file upload to work in a Grails 2.5.4 resource.
I'd really like to use Spring's out of the box multipart features, but I cannot find an example for my particular case.
I am calling the API from Postman. Body with form-data and a single PDF file attached in a file field. No other headers!
First try
#POST
#Path("/pdf")
Response createPdf(MultipartFile file)
Gives back 415 Unsuported Media Type in Postman, and this on the server:
[...] ERROR container.ContainerRequest - A message body reader for Java class org.springframework.web.multipart.MultipartHttpServletRequest [...]
The registered message body readers compatible with the MIME media type are:
*/* ->
com.sun.jersey.core.impl.provider.entity.FormProvider
com.sun.jersey.core.impl.provider.entity.StringProvider
com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
com.sun.jersey.core.impl.provider.entity.FileProvider
com.sun.jersey.core.impl.provider.entity.InputStreamProvider
com.sun.jersey.core.impl.provider.entity.DataSourceProvider
com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
com.sun.jersey.core.impl.provider.entity.ReaderProvider
com.sun.jersey.core.impl.provider.entity.DocumentProvider
com.sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader
com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader
com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General
com.sun.jersey.core.impl.provider.entity.EntityHolderReader
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$General
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$General
Adding #Consumes(MediaType.MULTIPART_FORM_DATA) does not help.
I've tried other params such as MultipartHttpServletRequest but there's still no message body reader.
Second try
#POST
#Path("/pdf")
#Consumes(MediaType.MULTIPART_FORM_DATA)
Response createPdf(#FormDataParam("file") InputStream uploadedInputStream,
#FormDataParam("file") FormDataContentDisposition fileDetail)
Gives back a 500 error, and this on the server:
SEVERE: Missing dependency for method public javax.ws.rs.core.Response com.carfax.VehicleReceiptPhotoResource.createPdf(java.io.InputStream,org.glassfish.jersey.media.multipart.FormDataContentDisposition) at parameter at index 0
SEVERE: Missing dependency for method public javax.ws.rs.core.Response createPdf(java.io.InputStream,org.glassfish.jersey.media.multipart.FormDataContentDisposition) at parameter at index 1
SEVERE: Method, public javax.ws.rs.core.Response createPdf(java.io.InputStream,org.glassfish.jersey.media.multipart.FormDataContentDisposition), annotated with POST of resource, class com.carfax.VehicleReceiptPhotoResource, is not recognized as valid resource method.
having these dependencies
compile group: 'com.sun.jersey', name: 'jersey-bundle', version: '1.19.4'
compile group: 'com.sun.jersey', name: 'jersey-json', version: '1.19.4'
compile "javax.ws.rs:javax.ws.rs-api:2.1#jar"
compile ('org.glassfish.jersey.media:jersey-media-multipart:2.27') {
exclude group:'javax.ws.rs'
}
compile group: 'org.jvnet.mimepull', name: 'mimepull', version: '1.9.11'
Third try
#POST
#Path("/pdf")
Response createPdf(#FormDataParam("file") InputStream fileInputStream)
With the same jersey dependencies as in the second attempt, this works, but it's not good enough for me. I'd like to upload multiple files at once, and get some extra json info on the side.
What I want
Some clarification on how many methods of multi file upload are there in Grails
What are the different libraries achieving this
To do this in a Grails REST resource, not in a controller
Some links I went through
Jersey Exception : SEVERE: A message body reader for Java class
https://groups.google.com/forum/#!topic/dropwizard-user/moYQOtxXnRU
Maven jersey-multipart missing dependency for javax.ws.rs.core.Response
https://philsturgeon.uk/api/2016/01/04/http-rest-api-file-uploads/
https://www.javatpoint.com/jax-rs-file-upload-example
JAX-RS Multipart with com.sun.jersey

*as per Paul Samsotha's comment
You're trying to mix Jersey 2.x multipart support with a Jersey 1.x application. This isn't going to work. You need to use the 1.x multipart. Get rid of the 2.x one.

Related

Classcastexception for CloudEventMessageConverter to AbstractMessageConverter

when using spring cloud stream latest version with cloud events spring sdk
Facing classcastexception in below scenario.
Message has contentType = application/*+avro.
SmartcompositeMessageConverter contains converter list like below -
CloudEventMessageConverter
AvroSchemaRegisteryClientMessageConverter
and some ootb converters.
While converting to message from producer..
SmartcompositeMessageConverter has this line of code for wildcard contentType
((AbstractMessageConverter) converter).getSupportedMimeTypes()
But CloudEventMessageConverter is not an instance of AbstractMessageConverter, hence it throws an exception.
Please guide what should be overridden in this case.
If I create a new CloudEventMessageConverter which extends AbstractMessageConverter, I cann't add headers as only method allowed to override is convertFromInternal which returns just the payload.

How to consume Soap Rpc encoded in spring boot?

Hello I managed to generate classes from wsdl using axis 1.4.But I am stuck at invoking services. I tried to used WebServiceTemplate and jaxb2marshaller but there is no request class generated. So I tried created request class manually based on the generated response class. But it is getting any response from server.It says xmlrootelement is not found. So i think jaxb2marshaller is not the correct way to invoke service since it is old rpc encoded soap wsdl. Suggest me the idea to invoke service.
Update:
when using axis 1.4
I found the solution to invoke methods.It is simple 2 line code.
SomeService service=new SomeServiceLocator().getSomeServicePort();
Sample sample=service.fetchSample();

GET /swagger-ui.html fails with HTTP 206

I'm using spring-boot 1.5.0 RELEASE with swagger 2.6.1. I've added #EnableSwagger2 annotation on my spring boot application and defined a #Bean of type Docket. I've not used #EnableWebMvc annotation anywhere. I've excluded swagger-ui.html from security. When i call /v2/api-docs, i get the correct response JSON. But when i call /swagger-ui.html, it fails with HTTP 206. In chrome, it fails with Failed - No file. In console it shows the following error - Resource interpreted as Document but transferred with MIME type multipart/byteranges: "http://localhost:8080/swagger-ui.html".

406 HTTP response in REST springboot service (XML)

I'm new to springboot development and JAVA, I'll be needing your help.
I have created a REST service using springboot to accept and produce message of XML format.
I have generated JAVA class files for XSD schema using JAXB plugin.
I'm able to pass the XML request to the REST service and display the values as well, but in response of service i'm getting 406 HTTP response.
I tried checking stackoverflow for any hint, i found that adding below dependency in pom will resolve the issue. When i added below dependency then i was able to get the proper XML response but then i was unable to get the input XML in the service, i want getting "NULL" object as input to service after adding dependency
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
Can you please help me and let me know how can i pass input XML request and get output XML response as well. Currently either one of the case is working for me.
Thank you
I have resolved this issue by adding #XmlRootElement annotation in all the JAXB generated java class files.
Hope this will help someone!

Force Spring to always report exceptions as JSON

How do I force Spring to always convert uncaught exception to JSON instead of HTML page?
This is what I get when request is made from Chrome's REST client plugin:
{
timestamp: 1425041457798
status: 404
error: "Not Found"
exception: "com.some.my.Exception"
message: "/rrr does not exist"
path: "/test/rrr"
}
But this is what I get when I access it from browser or from Jersey API (you see parsed HTML):
Whitelabel Error PageThis application has no explicit mapping for /error, so you are seeing this as a fallback.Fri Feb 27 13:37:27 CET 2015There was an unexpected error (type=Not Found, status=404).No message available
I know this can be done somehow by setting the request headers but I want JSON response to be the only variant.
First we need add some exception resolver for exception that trows inside controllers. I prefer extend ResponseEntityExceptionHandler and add own method, but there is a great article on spring.io: http://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
After that if you still get following page you can override org.springframework.boot.autoconfigure.web.ErrorController. There are an example: BasicErrorController. But this works only if you use spring boot application with embedded container. For example, if you will create war file form spring boot project and will deploy under tomcat, you will get standard tomcat error page.
So this mean that ErrorController is not common solution.
In my case i throws exceptions inside filters, that why /error page shown. So solution will be write own filter that converts exceptions to JSON representation. This solution should work for every container/server, and you can get more information about exception.

Resources