In Java Jersey (the JSR 311: JAX-RS reference implementation), you add Java Annotations to your POJOs to turn them in to RESTful resources. For example:
@Path("/posts")
public class PostsResource {
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public void post(@FormParam("title") String title, @FormParam("body") String body) {
// Save new post
}
}
I came across this post on StackOverflow, asking for a way to combine form params and query params in a single resource @POST
method. In other words, the poster wanted to know if he could do this:
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public void post(@BothParam("title") String title, @BothParam("body") String body) {
// Save new post
}
The annotation @BothParam
would allow you to create a post with either:
curl -d title=mytitle&body=mybody http://localhost:9998/posts
or:
curl -d body=mybody http://localhost:9999/posts?title=title
I'm also interested in a good solution to this question. I'm working on a project where I'd like to use Java Jersey, but need to support a legacy API which does not map elegantly into the RESTful paradigms that JAX-RS is designed to support.
One solution I'm exploring is an InjectableProvider
which provides an Injectable
for a custom annotation, such as BothParam
.
The custom annotation, BothParam
:
@Target({ ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface BothParam {
String value();
}
The injectable and injectable provider, BothParamInjectableProvider
:
@Provider
public class BothParamInjectableProvider implements Injectable<String>, implements Injectable<BothParam, Type> {
@Context HttpContext httpContext;
private String parameterName;
public BothParamInjectableProvider(@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 componentContext, BothParam bothParam, Type type) {
this.parameterName = bothParam.getValue;
return this;
}
}