How to use Parameters in REST Services

In this tutorial, we will learn how to use parameters in Java API for RESTful Web Services (JAX-RS) to pass data to the server and receive data from the server.

Overview of REST Parameters

Firstly, we recommend that you check out introduction to JAX-RS Services in this article: Getting started with RESTEasy and WildFly

JAX-RS is a Java API for creating RESTful web services. It provides a set of annotations and interfaces that allow you to define the URI paths, HTTP methods, and parameters for your web services.

Parameters are values that you can pass to a web service in the request URL or in the request body. They are can provide additional information to the server and to filter, sort, or paginate the Entity data.

JAX-RS provides several annotations and interfaces for working with parameters such as the following ones:

  • @FormParam
  • @PathParam
  • @QueryParam
  • @HeaderParam
  • @CookieParam
  • @MatrixParam
  • @BeanParam

Let’s explore all the possible interactions.

@FormParam

Firstly, we will learn the annotation @FormParam . You can use it to inject the parameters of a Web form into a REST service.JAX-RS REST parameters tutorial

For example, we are submitting an HTML POST request containing two parameters email and password:

<form method="POST" action="login">


Email Address: <input type="text" name="email">
<br>
Password: <input type="text" name="password">
<input type="submit">
 
</form>

On the server side, we can capture the Form Parameters as follows:

@Path("form")
@POST
@Consumes("application/x-www-form-urlencoded")
public String login(@FormParam("email") String e, @FormParam("password") String p) {   
   return "Logged with " + e + " " + p;
}

Finally, a quick way to test it with curl:

curl -X POST http://localhost:8080/rest-parameters/rest/form -H "Content-Type: application/x-www-form-urlencoded" -d "[email protected]&password=mypassword" 

As an alternative, you can bind the parameters email and password at class level, which can be useful if you need to re-use the same parameters across different methods of the service.

public class User {
 
  @FormParam("email")
  private String email;
  @FormParam("password")
  private String password;

}

Next, you need to modify the REST method accordingly:

@POST
@Path("form")
 public String login(@Form User form) {
 return "Logged with " + form.email + " " + form.password;
 }

Do you need to learn how to validate Form parameters in JAX-RS applications? Then check this article: How to validate Jakarta REST Endpoint values

@PathParam

The @PathParam annotation binds the value of a path segment to a resource method parameter. For example:

@GET
@Path("path/{id}")
public String loginPath(@PathParam("id") String id) {
    return "Id is " +id;
}

Finally, a quick way to test it with curl:

curl http://localhost:8080/rest-parameters/rest/path/11 

As for @FormParam, you can embed the @PathParam declaration at class level, if you prefer.

@QueryParam

The @QueryParam annotation binds the value of a path segment to a resource method parameter. For example, the following method would intercept an HTTP GET which contains the “id” parameter as Query parameter:

@GET
@Path("query")
public String loginQuery(@QueryParam("id") String id) {
    return "Id is " +id;
}

Then, a quick way to test it with curl:

curl http://localhost:8080/rest-parameters/rest/query?id=11

You can combine a QueryParam with the DefaultValue annotation to provide a default value for the parameter:

@GET
@Path("query")
public String loginQuery(@DefaultValue("11111")  @QueryParam("id") String id) {
    return "Id is " +id;
}

As for @FormParam, you can embed the @PathParam declaration at class level, if you prefer.

@HeaderParam

The @HeaderParam annotation extracts information from the HTTP header and binds it to a method parameter. Example:

@GET
@Path("header")
public String checkBrowser(@HeaderParam("User-Agent") String whichBrowser) {
  return "Browser is "+whichBrowser;
}

Then, a quick way to test it with curl:

curl http://localhost:8080/rest-parameters/rest/header

@CookieParam

You can use the @CookieParam annotation to inject a value from a cookie into a resource class method. For example:

@GET
@Path("session")
public String checkSession(@CookieParam("JSESSIONID") String sessionid) {
    return "Sessionid is "+sessionid;
}

And here is a little curl hack to inject the SessionId in the request:

curl -b "JSESSIONID=12345" http://localhost:8080/rest-parameters/rest/session

MultivaluedMap of Parameters

Next, we will check another approach for retrieving the REST Parameters is by means of the @Context annotation. Thus annotation allows you to inject parameters as a javax.ws.rs.core.MultivaluedMap. Here is for example how to retrieve the list of Cookies:

@GET
@Path("httpheaders")
public String getRequestHeaders(@Context HttpHeaders hh) {

    MultivaluedMap<String, String> headerParameters = hh.getRequestHeaders();
    Map<String, Cookie> params = hh.getCookies();
    StringBuffer sb = new StringBuffer();
    for (String key : params.keySet()) {
        sb.append(key + ": " + params.get(key));
    }
    return sb.toString();
}

Then, a quick way to test it with curl:

curl -b "Pragma=no-cache;Keep-Alive=300" http://localhost:8080/rest-parameters/rest/httpheaders

In the next example, we are injecting the @Context to retrieve the Query and Path parameters:

@GET
public String get(@Context UriInfo ui) {
 
    MultivaluedMap<String, String> queryParameters = ui.getQueryParameters();
    MultivaluedMap<String, String> pathParameters = ui.getPathParameters();
 
}

Actually you can inject several other resources with @Context such as javax.ws.rs.core.UriInfo, javax.ws.rs.core.Request, javax.servlet.HttpServletRequest, javax.servlet.HttpServletResponse, javax.servlet.ServletConfig, javax.servlet.ServletContext, and javax.ws.rs.core.SecurityContext objects.

@MatrixParam

The @MatrixParam annotation can be used to bind an expression containing several property=value to a method parameter. For example, supposing you were to invoke an URL like: http://localhost:8080/rest-parameters/rest/matrix;name=john;surname=smith

@GET
@Path("matrix")
public String callMatrix(@MatrixParam("name") String name,
                          @MatrixParam("surname") String surname) {
   return "name is "+name + " - surname is "+surname;
}

To test with curl, make sure you wrap the HTTP GET in literals:

curl -X GET "http://localhost:8080/rest-parameters/rest/matrix;name=john;surname=smith"

@BeanParam

Then, you can use the @BeanParam annotation to map all REST parameter in a Java class which works as a “parameter aggregator”.
The JAX-RS runtime will instantiate the object and inject all it’s fields and properties annotated with either one of the @XxxParam annotation (@PathParam, @FormParam …) or the @Context annotation. For the POJO classes same instantiation and injection rules apply as in case of instantiation and injection of request-scoped root resource classes.

Here is an example of a ParamBean:

public class ParamBean {
    @FormParam("username")
    String username;

    @FormParam("email")
    String email;

    @HeaderParam("Content-Type")
    String contentType;


    public String dumpData() {
        return "ParamBean{" +
                "username='" + username + '\'' +
                ", email='" + email + '\'' +
                ", contentType='" + contentType + '\'' +
                '}';
    }

}

Then, in your REST Service, use the @BeanParam to map the above Bean:

@POST
@Path("bean")
public String post(@BeanParam ParamBean bean) {
        return bean.dumpData();
}

You can test it with curl as follows:

curl -X POST http://localhost:8080/rest-parameters/rest/bean -H "Content-Type: application/x-www-form-urlencoded" -d "[email protected]&username=myuser" 

Reading REST Parameters Programmatically

Finally, if you don’t want to have more flexibility, you can use the javax.ws.rs.core.UriInfo class provides methods to enable you to find or build URI information of a request. This way, you don’t have to specify the parameter list in your method signature:

@GET
@Path("context")
public Response login(@Context UriInfo info) {
    String id = info.getQueryParameters().getFirst("username");
    return Response
            .status(200)
            .entity("login called with id: " + id).build();
}

Conclusion

This article was a walk through all the JAX-RS Parameters that you can use in a REST Application.

To learn how to Test this REST Service with REST Assured, check this article: How to test REST Services with RestAssured

You can find the source code for this example on GitHub at: https://github.com/fmarchioni/mastertheboss/tree/master/jax-rs/rest-parameters

Found the article helpful? if so please follow us on Socials