JAX-RS: case-insensitive paths - java

I have anchored REST services/methods to URI template by #Path annotation. It looks like as usual:
#GET
#Path("/message")
#Produces("application/json")
public Response getMessage() { ... }
But my REST service has to be case-insensitive. Now I'm using regular expression in #Path in all my code like that:
#GET
#Path("/{message:[mM][eE][sS][aA][gG][eE]}")
#Produces("application/json")
public Response getMessage() { ... }
This looks weird. Is there something I overlooked in specification (I hope not, see this) or has any of JAX-RS implementations special feature for that? Now I'm using JBoss RESTeasy.
Thanks.

i don't know resteasy, but if it supports all java regex syntax, you could use (?i:message) instead of your pattern.

If you really need to make the api case-insensitive and you're using Apache on the front-end of your site, consider doing it outside of code: define your API with the urls all lowercase and use Mod-Rewrite to change the urls to lowercase when they hit the web server no matter what the client actually sent. This blog post describes how to do this.

Also, the next pattern is working for me:
#Path("/{externalorders: (?i)externalorders}")

Related

How to specify path annotation in rest api java to accept any path?

I am using jersey rest service in java to accept request.
Here is my snippet
#Path("main")
public class xxxx{
#GET
#Path("test/{path}")
public void test(#Context HttpServletRequest req ) {
System.out.println(req.getRequestURI());
}
}
I am invoking this using REST Api as test/abcd , it is working. I want #path to accept test/abcd or test/abcd/ab and so. I tried with "test/{path}/*" nothing works.
Please someone help me as I am new to this.
You should use regex in the #Path for example :
#Path("{parameter: .*}")
Response getData(#PathParam("parameter") List<String> parameter){
//do processing
}
For more details you can see the examples given here.

JAX-WS #WebService on RESTful web-service endpoint

Some time ago in one of the projects I found #WebService annotations on some of the jersey root(#Path) resource classes. As far as I understood at the time it was some legacy code or simply a misused JAX-WS annotation. Recently I stumbled upon this post in which mixing JAX-RS service with #WebService annotation for the sake of EJB mentioned(as a side note, that project I worked on didn't make use of EJB at all, so I still think it was an improper use of #WebService). As a result of all that I am now confused if it is in general justifiable to mix #WebService and JAX-RS. What are the cases for that? Anything apart from EJB features mentioned?
Exposing a JAX-RS bean as the methods of a SOAP WS using #WebService may be technically possible. It will not lead to a good API design.
Consider some very common JAX-RS methods:
#GET
#Path("/foos")
#Produces("application/json")
public Response getFoos() {
// get all Foos
List<Foo> foos = ...;
return Response.ok(foos).build();
}
#GET
#Path("/foos/{id}")
#Produces("application/json")
public Response getSingleFoo(#PathParam("id") String id) {
// get the Foo
Foo foo = ...;
return Response.ok(foo).build();
}
It is immediatley obvious how the URLs to call these methods will be structured and what the result will be.
But exposing these methods using #WebService leads to many questions:
What is a Response in a SOAP response?
Will the response use JSON as the representation?
How are the methods called?
I can imagine no usecase that is not completely trivial for which it makes sense to expose the same method using both JAX-RS and JAX-WS. It can either be a useful method for one but not for both.
Don't do this.

Jax-rs Regex path

I have this Jax-rs service interface:
#GET
#Path("{id: ^((?!_ah).)*$}")
#Produces(MediaType.TEXT_HTML)
public Response getStuff(#PathParam("id") String id, #Context HttpHeaders headers,
#Context UriInfo uriInfo, #Context SecurityContext securityContext);
The goal of this interface is to catch all character sequence except for:
_ah/foo
_ah/foo/bar
Or anything start starts with _ah
I tried the regex in: http://rubular.com/
And from what it seems it works as expected. However my problem now is that when I access a the supposedly bypassed path I get this:
Could not find resource for relative : /_ah/admin of full path: http://127.0.0.1:8888/_ah/admin
My app runs on GAE, so when running on dev mode, this _ah path is used for management servlets on the SDK runtime.
What am I missing? Isn't it that when the #Path filter does not match it will bypass it? So why do I get Cannot find resource problem?
If I don't put: #Path("{id: ^((?!_ah).)*$}") the servlets under _ah path works fine. Isn't it that the _ah path is already bypassed and should be accessible again?
I ran into this problem while upgrading RestEasy to 3.0.10. I had a #Path("{id}") and #Path("jobs") conflict that came from legacy code. Because of 3rd party apps, I couldn't change my rest endpoints without a lengthy process. Fortunately the regex solution did work for me. Though I can't say why it didn't work for the original poster.
This caused me a few days of headache both figuring out where my problem was and how to solve it. I share this in case you are in a similar situation and changing your rest endpoint isn't a viable option.
Original class:
#Path("device")
public class DeviceApi
{
#PUT
#Path("{id}")
public Device deviceAction(..., Device device) {...}
}
Conflicting regex class:
#Path("device")
public class JobsDeviceApi
{
#PUT
#Path("jobs")
public void moveJobs(..., Jobs jobs)
}
Modified DeviceApi class that works:
#Path("device")
public class DeviceApi
{
#PUT
#Path("{id: ^(jobs)}")
public Device deviceAction(..., Device device) {...}
}
Obviously you can put whatever regex you want in there. I only need it to ignore that single path so I used the KISS principle (Keep it simple stupid).

How can a JAX-RS REST service have authentication handled by annotations?

I have a REST api written with JAX-RS, and I need to add authentication to it. So far all the information I've been able to find about it has suggestions for doing it via spring, which I'm not using. Is there something already existing, or would it be easy to write, something that will let me annotate either a method, or the entire class which would force auth headers to be present?
I'm using tomcat6 and jersey, if that matters.
Something like:
#Path("api")
public class Api {
#GET
#AuthenticationRequired
public Response getInfo(...) {...}
}
I think you want import javax.annotation.Security.RolesAllowed;
The annotation itself looks like this
#Path("/helloworld")
#RolesAllowed({"ADMIN", "ORG1"})
public class helloWorld {
#GET
#Path("sayHello")
#Produces("text/plain")
#RolesAllowed("ADMIN")
public String sayHello() {
return "Hello World!";
}
}
I would manage security at the container level. Here's a good writeup if you happen to be using Apache CXF:
http://cxf.apache.org/docs/secure-jax-rs-services.html
And here's an example for Glassfish:
http://www.butonic.de/2010/06/18/a-simple-jax-rs-security-context-example-in-glassfish/
Here's one more link, which discusses JSR 250 annotations (e.g. #RolesAllowed):
http://www-01.ibm.com/support/knowledgecenter/SSEQTP_8.5.5/com.ibm.websphere.base.doc/ae/twbs_jaxrs_impl_securejaxrs_annotations.html

Java using Spring restful URL

I am using Java with Spring framework.
I have a multiaction controller which is having lots of service methods, and I want to to create restful URLs like as following:
http://server.com/url/events/multiActionMethod1
http://server.com/url/events/multiActionMethod2
http://server.com/url/events/multiActionMethod3
http://server.com/url/events/multiActionMethod4
http://server.com/url/events/multiActionMethod5
How can I achieve above tasks?
I think maybe something isn't coming through clearly in your question. It reads like all you're looking for is this:
#RequestMapping("/events/multiActionMethod1")
public ReturnType multiActionMethod1(SomeParameter param) {
//request handling logic
}
is there more to the question you could elaborate on?
edit: ugh no, none of that is in 2. You'd need 2.5 for annotations and 3 if you want support for using parts of the url as parameters. The easiest thing to do if you really want it to work that way in an older version is slap a URL rewriter on the front and convert it to regular query string before it hits spring.

Categories