Whiteboard JAX-RS Multipart
phhoef opened this issue · 14 comments
Hi guys,
I encountered another problem and I was hoping you could help me out, again.
I am trying to process a request containing a multipart/form-data.
As far as I understood beginning from v3 the HttpServletRequest can parse the form-data without the need of any library.
I extended my small osgi-test app by another controller for the multipart endpoint.
https://github.com/phhoef/osgi-test/blob/master/rest-service/src/main/java/com/my/app/rest/rest/MultipartController.java
Whenever I am trying to invoke the getParts()
method the following exception is thrown:
<h2>HTTP ERROR 500</h2>
<p>Problem accessing /multipart. Reason:
<pre> Server Error</pre>
</p>
<h3>Caused by:</h3>
<pre>java.lang.IllegalStateException: Multipart not enabled for servlet.
at org.apache.felix.http.base.internal.dispatch.ServletRequestWrapper.checkMultipart(ServletRequestWrapper.java:368)
at org.apache.felix.http.base.internal.dispatch.ServletRequestWrapper.getParts(ServletRequestWrapper.java:522)
at javax.servlet.http.HttpServletRequestWrapper.getParts(HttpServletRequestWrapper.java:345)
at com.my.app.rest.rest.MultipartController.post(MultipartController.java:22)
I understand, that I have to activate multipart for that Servlet.
I didn't find much on the internet, only some posts stating either using @MultipartConfig
or the @HttpWhiteboardServletMultipart
annotation.
For the @MultipartConfig
I modified the controller. I subclassed the HttpServlet
and set the @Component(service=Servlet.class)
.
https://blog.osgi.org/2018/05/osgi-r7-highlights-http-whiteboard.html
But both annotations do not influence the behavior.
Do I miss something?
You have the correct configuration using @HttpWhiteboardServletMultipart
.
It looks like it might be a problem/bug with org.apache.felix.http
.
thanks for your quick reply.
At least it seems to be not my fault :-)
Is there any way to verify your guess?
Do you think, that there might be a workaround?
I can look when I have time but I'm not sure where that will be. Maybe sending a message to the felix mail list might provide some insight?
thanks, will do so
I found out, that using the classic way and override the doPost
method the @HttpWhiteboardServletMultipart
annotation will work.
@Component(service=Servlet.class)
@HttpWhiteboardServletMultipart
@HttpWhiteboardServletPattern("/multipart")
public class MultipartController extends HttpServlet
{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
Collection<Part> parts = req.getParts();
for (Part part : parts)
{
System.out.printf("File %s, %s, %d%n", part.getName(),
part.getContentType(), part.getSize());
}
}
}
I am still searching for a solution using the JAX-RS way with multipart...
Whenever I am trying to invoke the getParts() method the following exception is thrown:
This appears to be an intentional limitation of the JAX-RS whiteboard implementation from Aries, which has not requested that multipart be enabled. Fortunately the Aries JAX-RS whiteboard is pretty flexible, and allows you to configure the properties of the servlet it registers. This should be as simple as adding:
osgi.http.whiteboard.servlet.multipart.enabled=true
as a configuration property for the whiteboard. Assuming that you are using the default whiteboard this pid would be org.apache.aries.jax.rs.whiteboard.default
. At this point multipart will be enabled for your JAX-RS whiteboard.
Once you have done this then you can use multipart however you wish, although I would suggest that a more natural approach involves using the @FormParam
annotation.
Thanks @timothyjward and thanks @rotty3000 for your patient and your answers.
I know most of my questions are off topic. So, I really appreciate your reply :-)
I am sorry, but I didn't understand your answer completely.
I understand, that I can activate the multipart for a JAX-RS Whiteboard resource, by adding the mentioned property.
But I am afraid, I am failing in setting this property.
@Component(service=MultipartController.class, property = {"osgi.http.whiteboard.servlet.multipart.enabled=true"})
@JaxrsResource
@Path("/multipart")
public class MultipartController
{
@POST
public void post(@Context HttpServletRequest request) throws Exception
{
for(Part part : request.getParts())
{
System.out.println(part.getName());
}
}
}
Is there something wrong?
Exception still says multipart is not enabled.
Thanks
I understand, that I can activate the multipart for a JAX-RS Whiteboard resource, by adding the mentioned property.
I’m afraid that this is a misunderstanding, and I may have been insufficiently clear. There is no property you can add to your JAX-RS resource service to enable multipart support. Note that this does not mean that you cannot enable multipart support, but you must do it elsewhere.
Most JAX-RS whiteboards build on top of the Http Service Whiteboard by registering a whiteboard Servlet, which they then use to provide endpoints for all of their resources. Aries JAX-RS is one of these implementations. The available support from the web container is therefore entirely dictated by the service properties of the implementation’s whiteboard Servlet, not the service properties of the JAX-RS resources. Even if the JAX-RS whiteboard created its own web server, it would still be this configuration we needed to alter, not the properties of your whiteboard resource.
To enable multipart support we must therefore add to the service properties of the JAX-RS whiteboard’s implementation. You can do this by changing the configuration of the whiteboard using a configuration admin dictionary as I described earlier. This would be a new entry in your JSON configuration file.
For belt and braces you could further require that this property had been set by using a whiteboard target for your JAX-RS resource service (this would be a service property on your service). This filter could require that the osgi.http.whiteboard.servlet.multipart.enabled
property was true.
I totally misunderstood your first post.
Thanks for clarification :-)
Hi @timothyjward , Can you please let me know where I can add the property "osgi.http.whiteboard.servlet.multipart.enabled" to JAX-RS whiteboard configuration
Hi @timothyjward , Can you please let me know where I can add the property "osgi.http.whiteboard.servlet.multipart.enabled" to JAX-RS whiteboard configuration
As described further up this bug, if you want to enable this for the default whiteboard then the configuration pid is org.apache.aries.jax.rs.whiteboard.default
, otherwise it goes in the factory configuration that you are adding to create a new whiteboard instance.
@timothyjward I wonder if there would be any downside with making this the default?
@timothyjward I wonder if there would be any downside with making this the default?
It would require the hosting Servlet container to always support multipart, which is a relatively uncommon feature to need in a JAX-RS app. As is we can run on containers which don’t support multipart.
that's a good point. thanks for the thought experiment. retracting the idea :)