JAX-RS @Path URI Matching Example
In this example we are going to see how to use @Path
annotation in a JAX-RS application to assign a certain URI, or a certain form of URIs into a specific method.
In this example we are not going to focus on how to create JAX-RS application from top to bottom. So make sure you read carefully Jersey Hello World Example and RESTEasy Hello World Example, and pay attention to the sections concerning the creation of the project with Eclipse IDE as well as the deployment of the project in Tomcat.
The code of this tutorial is going to be based on Jersey Hello World Example. You can download the Eclipse project of this tutorial here : JAXRS-HelloWorld.zip
1. Project structure
Let’s remind ourselves the structure of the project we are working on:
The code presented in this new tutorial will only concern HelloWorldREST.java
file.
At this point you can also take a look at the web.xml
file to see how the project is configured:
web.xml:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>Restful Web Application</display-name> <servlet> <servlet-name>jersey-helloworld-serlvet</servlet-name> <servlet-class> com.sun.jersey.spi.container.servlet.ServletContainer </servlet-class> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> <param-value>com.javacodegeeks.enterprise.rest.jersey</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>jersey-helloworld-serlvet</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> </web-app>
As you can see our servlet is mapped to /rest/ URI pattern. So the basic structure of the URIs used in this example will have the form :
http://localhost:8080/JAXRS-HelloWorld/rest/....
So let’s see how to use @Path annotation to associate a certain URI to a specific method of your REST API.
2. Normal URI Matching
Imagine that you have a school-like database structure that has members, and members can be students and teachers. You want to make an REST API that will return a list of all members and then specifically the list of students and the list of teachers. Let’s see how you could do that:
HelloWorldREST.java:
package com.javacodegeeks.enterprise.rest.jersey; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.core.Response; @Path("/members") public class HelloWorldREST { @GET public Response getMembers() { String output = " This is the list of our members:"; // . . . work to retrieve the list of members return Response.status(200).entity(output).build(); } @GET @Path("/teachers") public Response getTeachers() { String output = " This is the list of our teachers:"; // . . . work to retrieve the list of teachers return Response.status(200).entity(output).build(); } @GET @Path("/students") public Response getStudents() { String output = " This is the list of our students:"; // . . . work to retrieve the list of students return Response.status(200).entity(output).build(); } }
When you put on your browser:
http://localhost:8080/JAXRS-HelloWorld/rest/members
Outputs:
This is the list of our members:
http://localhost:8080/JAXRS-HelloWorld/rest/members/students
Outputs:
This is the list of our students:
http://localhost:8080/JAXRS-HelloWorld/rest/members/teachers
Outputs:
This is the list of our teachers:
3. Parametrized URI Matching
This works similarly to the normal URI matching, except this enables user input and the form of the URI is not restricted to /students
or /members
. The user can put any form of URI he wants. Then the method can parse that URI and act accordingly. For example let’s say we wan to list all information available about a member and the client has to provide just a username:
HelloWorldREST.java:
package com.javacodegeeks.enterprise.rest.jersey; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.Response; @Path("/members") public class HelloWorldREST { @GET @Path("/{username}") public Response getMemberInfo( @PathParam("username") String username ) { String output = " This is all the info on : " + username; // . . . work to retrieve the info of {username} return Response.status(200).entity(output).build(); } }
As you can see we define a Path Parameter using /{ parameter_name }
syntax ( you can also just put { parameter_name }
without the /). The Path Parameter can be parsed using @PathParam
annotation, on the argument of getMemberInfo
method. If parsed correctly, the value of the Path Parameter will be available to the method through the String username
variable.
When you put on your browser:
http://localhost:8080/JAXRS-HelloWorld/rest/members/james
Outputs:
This is all the info on : james
http://localhost:8080/JAXRS-HelloWorld/rest/members/lisa
Outputs:
This is all the info on : lisa
4. Regular Expression URI Matching
When you want to bind your method to a specific form of URI then you can easily use regular expressions to achieve that. For example, let’s say you want to add a member, but you want the username to have only letters and no digits. Furthermore, you want to see information about a certain class, but class codes only contain digits and not numbers. Let’s see how you could do that:
HelloWorldREST.java:
package com.javacodegeeks.enterprise.rest.jersey; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.Response; @Path("/members") public class HelloWorldREST { @GET @Path("addmember/{username : [a-zA-Z]+}") public Response addMember( @PathParam("username") String username ) { String output = " Will add member: " + username; // . . . work to add {usrname} as a member return Response.status(200).entity(output).build(); } @GET @Path("class/{code : \\d+}") public Response getClassInfo( @PathParam("code") int id ) { String output = " This is all the info on class : " + id; // . . . work to get info of class with id = {id} return Response.status(200).entity(output).build(); } }
As you can see we use regular expressions in the parameters with { parameter_name : regex }
syntax.
When you put on your browser:
http://localhost:8080/JAXRS-HelloWorld/rest/members/addmember/luke
Outputs:
Will add member: luke
but
When you put on your browser:
http://localhost:8080/JAXRS-HelloWorld/rest/members/addmember/luke123
Outputs:
HTTP Status 404 - Not Found
...
description The requested resource is not available.
And
http://localhost:8080/JAXRS-HelloWorld/rest/members/class/1283
Outputs:
This is all the info on class : 1283
But
http://localhost:8080/JAXRS-HelloWorld/rest/members/class/1283abc
Outputs:
HTTP Status 404 - Not Found
...
description The requested resource is not available.
This was an Example JAX-RS @Path URI Matching.