We define named URI path parameters in @Path
expression. Its value is injected using @javax.ws.rs.PathParam
annotation.
Dependencies
See @Path annotation for details.
PathParam Example
We define a path parameter in @Path
and its value is injected using @PathParam
.
In the below example, class level @Path("/product/{productName}")
annotation hold parameter productName
. We inject the product name using @PathParam("productName")
. See method findProductByName()
.
Its possible to refer to multiple path parameters. In findProductByid()
, we refer to more than one URI path parameter, product name and its ID.
PathParamExamples:
package com.javarticles.rest; import java.util.List; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.PathSegment; @Path("/product/{productName}") @Produces(MediaType.TEXT_PLAIN) public class PathParamExamples { @GET public String findProductByName(@PathParam("productName") String name) { return "Find products by name <" + name + ">"; } @Path("{id}") @GET public String findProductByid(@PathParam("productName") String name, @PathParam("id") String id) { return "Find products by name <" + name + ">, id <" + id + ">"; } }
Enter http://localhost:8280/myapp/product/bed
in browser.
Output:
Find products by name <bed>
Enter <codehttp://localhost:8280/myapp/product/bed/7188 in browser.
Output:
Find products by name <bed>, sku <7188>
PathSegment Example
We now know that @PathParam
injects value of the parameter defined in @Param
annotation. The parameter value being a string naturally maps to a method argument whose type is a string. If the URI contains a matrix of parameters, for example, http://localhost:8280/myapp/product/bed/details;size=king;color=teak/9199
. If you want to access the path and matrix parameters (text in blue), then the type of the value that PathParam
injects can’t be string any more. We need some abstraction using which we can access the path as well as the matrix parameters and this where class PathSegment
comes in.
package javax.ws.rs.core; public interface PathSegment { String getPath(); MultivaluedMap<String, String> getMatrixParameters(); }
The value that @PathParam
injects can be of type javax.ws.rs.core.PathSegment
, this way we have access to both path and matrix parameters.
PathParamExamples:
package com.javarticles.rest; import java.util.List; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.PathSegment; @Path("/product/{productName}") @Produces(MediaType.TEXT_PLAIN) public class PathParamExamples { @GET public String findProductByName(@PathParam("productName") String name) { return "Find products by name <" + name + ">"; } @Path("{id}") @GET public String findProductByid(@PathParam("productName") String name, @PathParam("id") String id) { return "Find products by name <" + name + ">, id <" + id + ">"; } @Path("{details}/{id}") @GET public String findProductByDetails(@PathParam("productName") String name, @PathParam("details") PathSegment pathSegment, @PathParam("id") String id) { MultivaluedMap<String, String> map = pathSegment.getMatrixParameters(); StringBuilder sb = new StringBuilder(); sb.append(pathSegment.getPath()); for (String key : map.keySet()) { sb.append("key=").append(key).append(",").append("value=") .append(map.get(key)).append("|"); } return "Find products by name <" + name + ", details <" + sb + ">"; } }
Enter http://localhost:8280/myapp/product/bed/details;size=king;color=teak/9199
in browser.
Output:
Find products by name <bed, details <detailskey=size,value=[king]|key=color,value=[teak]|>
Matching Multiple PathSegments
Sometimes the expression in @Path
annotation can result in more than one path segments.
For example, if the path expression is:
code>”product/{productName}/{details: .+}/group/{group}” and
the URI is http://localhost:8280/myapp/product/bed/storage/details;make=teak;size=king/group/bestsellers
,
then path parameter details
holds two path segments.
storage
details;make=teak;size=king
Since there are more than one path segments and we need to make sure that the type of the parameter is a list of PathSegments so that both the segments can be injected. See findProductByMultipleDetails()
, the details
parameter is of type List<PathSegment>
.
PathParamExamples:
package com.javarticles.rest; import java.util.List; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.PathSegment; @Path("/product/{productName}") @Produces(MediaType.TEXT_PLAIN) public class PathParamExamples { @GET public String findProductByName(@PathParam("productName") String name) { return "Find products by name <" + name + ">"; } @Path("{id}") @GET public String findProductByid(@PathParam("productName") String name, @PathParam("id") String id) { return "Find products by name <" + name + ">, id <" + id + ">"; } @Path("{details}/{id}") @GET public String findProductByDetails(@PathParam("productName") String name, @PathParam("details") PathSegment pathSegment, @PathParam("id") String id) { MultivaluedMap<String, String> map = pathSegment.getMatrixParameters(); StringBuilder sb = new StringBuilder(); sb.append(pathSegment.getPath()); for (String key : map.keySet()) { sb.append("key=").append(key).append(",").append("value=") .append(map.get(key)).append("|"); } return "Find products by name <" + name + ", details <" + sb + ">"; } @Path("{details: .+}/group/{group}") @GET public String findProductByMultipleDetails( @PathParam("productName") String name, @PathParam("details") List<PathSegment> pathSegmentList, @PathParam("group") String group) { StringBuilder sb = new StringBuilder(); for (PathSegment ps : pathSegmentList) { sb.append("Path="); sb.append(ps.getPath()); sb.append(", key/value={"); MultivaluedMap<String, String> map = ps.getMatrixParameters(); for (String key : map.keySet()) { sb.append("key=").append(key).append(",").append("value=") .append(map.get(key)).append("|"); } sb.append("}|"); } return "Find products by name <" + name + ">, details <" + sb + ">" + ", group <" + group + ">" ; } }
Enter http://localhost:8280/myapp/product/bed/storage/details;make=teak;size=king/group/bestsellers
in browser.
Output:
Find products by name <bed>, details <Path=storage, key/value={}|Path=details, key/value={key=size,value=[king]|key=make,value=[teak]|}|>, group <bestsellers>
Download the source code
This was an example about JAX-RS @PathParam Annotation.