Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Whiteboard JAX-RS Multipart #65

Closed
phhoef opened this issue Jun 29, 2018 · 14 comments
Closed

Whiteboard JAX-RS Multipart #65

phhoef opened this issue Jun 29, 2018 · 14 comments

Comments

@phhoef
Copy link

phhoef commented Jun 29, 2018

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?

@rotty3000
Copy link
Contributor

You have the correct configuration using @HttpWhiteboardServletMultipart.

It looks like it might be a problem/bug with org.apache.felix.http.

@phhoef
Copy link
Author

phhoef commented Jun 29, 2018

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?

@rotty3000
Copy link
Contributor

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?

@phhoef
Copy link
Author

phhoef commented Jun 29, 2018

thanks, will do so

@phhoef phhoef closed this as completed Jun 29, 2018
@phhoef
Copy link
Author

phhoef commented Jul 2, 2018

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...

@phhoef phhoef reopened this Jul 2, 2018
@timothyjward
Copy link
Contributor

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.

@phhoef
Copy link
Author

phhoef commented Jul 2, 2018

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

@timothyjward
Copy link
Contributor

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.

@phhoef
Copy link
Author

phhoef commented Jul 2, 2018

I totally misunderstood your first post.
Thanks for clarification :-)

@sarath-budam-tfs
Copy link

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

@timothyjward
Copy link
Contributor

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.

@rotty3000
Copy link
Contributor

@timothyjward I wonder if there would be any downside with making this the default?

@timothyjward
Copy link
Contributor

@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.

@rotty3000
Copy link
Contributor

that's a good point. thanks for the thought experiment. retracting the idea :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants