JAX-RS @QueryParam Example

The JAX-RS @QueryParam annotation allows you to inject URI query parameters into your Java parameters. These query parameters are represented as a string of characters within the HTTP request. JAX-RS can convert this string data into any Java type that you want, provided that it matches the specified type.

Mapping Query Parameters with @QueryParam

Here is an example how you can map the query parameters from the HTTP request to the correct type as Java parameters. JAX-RS handles the automatic type conversion.

package com.memorynotfound.rs;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.util.List;

@Path("/customers")
public class CustomerResource {

    @GET
    public Response getCustomers(@QueryParam("offset") Integer offset,
                                 @QueryParam("size") Integer size,
                                 @QueryParam("orderBy") List<String> orderBy){

        return Response
                .ok()
                .entity("customers with offset: " + offset +
                        ", size: " + size +
                        ", orderBy: " + orderBy)
                .build();
    }

}

When we use the following HTTP request: GET /customers?offset=100&size=10&orderBy=firstName,lastName we receive the following response:

customers with offset: 100, size: 10, orderBy: [firstName,lastName]

Passing Collection in Query Parameters

You can pass a collection in query parameters in 2 ways.

  1. Repeated values: orderBy=name&orderBy=price
  2. Comma separated values: orderBy=name,price

Getting Query Parameters Programatically

You may have the need to iterate through all query parameters defined on the request URI. You can use the UriInfo#getQueryParameters() method, that gives you a map containing all the query parameters. You can inject an instance of the UriInfo using the @Context annotation.

package com.memorynotfound.rs;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.util.List;

@Path("/orders")
public class OrderResource {

    @GET
    public Response getOrders(@Context UriInfo info){

        String offset = info.getQueryParameters().getFirst("offset");
        String size = info.getQueryParameters().getFirst("size");
        List<String> orderBy = info.getQueryParameters().get("orderBy");

        for (String name : info.getQueryParameters().keySet()){
            System.out.println("query param name: " + name + " value: " + info.getQueryParameters().getFirst(name));
        }

        return Response
                .ok()
                .entity("orders with offset: " + offset +
                        ", size: " + size +
                        ", orderBy: " + orderBy)
                .build();
    }

}

When we use the following HTTP request: /orders?offset=10&size=10&orderBy=name&orderBy=price we receive the following response:

orders with offset: 10, size: 10, orderBy: [name, price]

Specify Default Value for Query Parameter with @DefaultValue

You can specify a default value in case no value is passed in the query parameter. The @DefaultValue annotation is used before the query parameter and you can pass in a string value containing a default value for that query parameter. If you need to add a default value for a list or a set, you can pass comma separated values to instantiate the list with multiple values.

package com.memorynotfound.rs;

import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.util.List;

@Path("/products")
public class ProductResource {

    @GET
    public Response getProducts(@DefaultValue("0") @QueryParam("offset") Integer offset,
                                @DefaultValue("10") @QueryParam("size") Integer size,
                                @DefaultValue("firstName, lastName") @QueryParam("orderBy") List<String> orderBy){

        return Response
                .ok()
                .entity("products with offset: " + offset +
                        ", size: " + size +
                        ", orderBy: " + orderBy)
                .build();
    }

}

When we use the following HTTP request: /products we receive the following response:

products with offset: 0, size: 10, orderBy: [firstName, lastName]

Passing Query Parameters in JAX-RS Client

You can pass query parameters using the WebTarget#queryParam(name, value) method. This is a nice convenience method to use, especially if your values might have characters that need to be encoded.

package com.memorynotfound.rs;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.Response;
import java.util.Arrays;

public class RunClient {

    public static void main(String... args){
        Client client = ClientBuilder.newClient();

        Response response = client
                .target("http://localhost:8081/jaxrs-query-param/api/products")
                .queryParam("offset", 40)
                .queryParam("size", 20)
                .queryParam("orderBy", Arrays.asList("name", "age"))
                .request()
                .get();

        if (response.getStatus() == 200){
            System.out.println("Response: " + response.readEntity(String.class));
        }
        client.close();
    }
}

References

Download

You may also like...