In Jersey, can I combine QueryParams and FormParams into one value for a method?

I have a function like:

@POST @Path("/create") @Produces({MediaType.APPLICATION_JSON}) public Playlist createPlaylist(@FormParam("name") String name) { Playlist p = playlistDao.create(); p.setName(name); playlistDao.insert(p); return p; } 

I want the "name" parameter to come from the form OR from the request parameter. If the user is sent to / playlist / create /? Name = bob, then I want it to work. (This mainly helps when testing the API, but also for using it on different platforms without a browser.)

I would like to subclass everything that makes magic binding work ... (@BothParam ("name") String name), but it will need some help to make this happen, since I'm new to Jersey / Java Servlets services.


Update: the next day ...

I solved this by implementing a ContainerRequestFilter that combines form parameters into request parameters. This is not the best solution, but it seems to work. I was not lucky to connect something to the form parameters.

Here's the code in case someone is looking for it:

 @Override public ContainerRequest filter(ContainerRequest request) { MultivaluedMap<String, String> qParams = request.getQueryParameters(); Form fParams = request.getFormParameters(); for(String key : fParams.keySet()) { String value = fParams.get(key).get(0); qParams.add(key, value); } } 

I would still appreciate it if there was a better way to do this, so I will leave this question open.

+6
source share
1 answer

One way to do this is with InjectableProvider .

First you define the BothParam annotation:

 @Target({ ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) public @interface BothParam { String value(); } 

Then define an InjectableProvider for it:

 @Provider public class BothParamProvider implements Injectable<String>, InjectableProvider<BothParam, Type> { @Context private HttpContext httpContext; private String parameterName; public BothParamProvider(@Context HttpContext httpContext) { this.httpContext = httpContext; } public String getValue() { if (httpContext.getRequest().getQueryParameters().containsKey(parameterName)) { return httpContext.getRequest().getQueryParameters().getFirst(parameterName); } else if(httpContext.getRequest().getFormParameters().containsKey(parameterName)) { return httpContext.getRequest().getFormParameters().getFirst(parameterName); } return null; } public ComponentScope getScope() { return ComponentScope.PerRequest; } public Injectable getInjectable(ComponentContext cc, BothParam a, Type c) { parameterName = a.value(); return this; } } 

Please note that this is not really a connection between QueryParam and FormParam . Goals annotated by any of them are introduced in a more complex way. However, if your needs are quite limited, the method described above may work for you.

+3
source

Source: https://habr.com/ru/post/905033/


All Articles