При использовании JAX-RS при написании REST методов для обработки пользовательских запросов встает вопрос, как лучше передавать параметры запроса на сервер. Для этого существуют различные способы, о двух из которых тут пойдет речь. Параметры можно передавать используя @PathParam или @QueryParam. В чем разница при передаче параметров с использованием @PathParam и @QueryParam я хочу рассказать в этой статье.
При использовании JAX-RS при написании REST методов для обработки пользовательских запросов встает вопрос, как лучше передавать параметры запроса на сервер. Для этого существуют различные способы, о двух из которых тут пойдет речь. Параметры можно передавать используя @PathParam или @QueryParam. В чем разница при передаче параметров с использованием @PathParam и @QueryParam я хочу рассказать в этой статье.
Краткое описание
Необходимо получить список заказчиков, посылая на сервер один или несколько параметров. Эти параметры можно посылать как часть URL (тогда используется @PathParam) или как часть самого запроса ( тогда параметр посылается при помощи @QueryParam). Если мы посылаем параметр как часть URL то просто добавляем его к адресу через знак /. Например,
rest/customers/getCustomers/ABCD123 - где ABCD123 - посылаемый параметр (строковый id).
Если посыламем параметр как часть запроса, то используем специальный синтаксис.
Перед тем как перечислять параметры ставим значк вопроса ? потом ставим имя параметра потом знак равно = потом значение параметра. Если параметров больше одного то между ними ставится знак &. Например, для того чтобы отправить два параметра placeId и placeId нужно написать так:
/rest/customers/getCustomers?placeId=PAD1234C&placeId=90321
Ресурс, который будет обрабатывать запросы
package ru.ipoint.rest.server.resource; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @Path("/customers") public class MyRestService { private MyRestManager manager = MyRestManager.getInstance(); // Если мы используем @PathParam // то необходимо добавлять параметр в URL @Path("/getCustomers/{placeId}") @GET @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response getCustomersByPathParam(@PathParam("placeId") String placeId) { return Response.ok(manager.getCustomers(placeId)).build(); } // @PathParam с двумя параметрами @Path("/getCustomers/{placeId}/{orderId}") @GET @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response getCustomersByPathParams( @PathParam("placeId") String placeId, @PathParam("orderId") Long orderId) { return Response.ok(manager.getCustomers(placeId, orderId)).build(); } // Если мы используем @QueryParam // то в URL ничего добавлять не надо @Path("/getCustomers") @GET @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response getCustomersByQueryParam( @QueryParam("placeId") String placeId) { return Response.ok(manager.getCustomers(placeId)).build(); } // @QueryParam с двумя параметрами @Path("/getCustomersWithOrder") @GET @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response getPlacesByQueryParam( @QueryParam("placeId") String placeId, @QueryParam("orderId") Long orderId) { return Response.ok(manager.getCustomers(placeId, orderId)).build(); } }
Класс, из которого мы будем формировать и отправлять запросы на сервер
package ru.ipoint.rest.client; import com.google.gwt.http.client.RequestBuilder; import com.google.gwt.http.client.RequestException; public class RestTest { public static void main(String[] args) { String placeId = "PAD1234C"; int orderId = 90321; // запрос с использованием @PathParam, где 1 параметр RequestBuilder requestBuilder1 = new RequestBuilder(RequestBuilder.GET, "/rest/customers/getCustomers/" + placeId); try { requestBuilder1.send(); } catch (RequestException e) { e.printStackTrace(); } // запрос с использованием @PathParam, где 2 параметра RequestBuilder requestBuilder2 = new RequestBuilder(RequestBuilder.GET, "/rest/customers/getCustomers/" + placeId + "/" + orderId); try { requestBuilder2.send(); } catch (RequestException e) { e.printStackTrace(); } // запрос с использованием @QueryParam, где 1 параметр RequestBuilder requestBuilder3 = new RequestBuilder(RequestBuilder.GET, "/rest/customers/getCustomers?placeId=" + placeId); try { requestBuilder3.send(); } catch (RequestException e) { e.printStackTrace(); } // запрос с использованием @QueryParam, и где 2 параметра RequestBuilder requestBuilder4 = new RequestBuilder(RequestBuilder.GET, "/rest/customers/getCustomers?placeId=" + placeId + "&orderId=" + orderId); try { requestBuilder4.send(); } catch (RequestException e) { e.printStackTrace(); } } }
Так будут выглядеть сформированные адреса запросов
1. Запрос с использованием @PathParam, где 1 параметр
/rest/customers/getCustomers/PAD1234C
2. Запрос с использованием @PathParam, где 2 параметра
/rest/customers/getCustomers/PAD1234C/90321
3. Запрос с использованием @QueryParam, где 1 параметр
/rest/customers/getCustomers?placeId=PAD1234C
4. Запрос с использованием @QueryParam, и где 2 параметра
/rest/customers/getCustomers?placeId=PAD1234C&orderId=90321
Выводы
Рекомендуется все необходимые параметры добавлять в path (то есть в @PathParam). А параметры, которые являются опциональными, почти всегда являются строковыми параметрами. Добавление опциональных параметров в URL может привести к очень запутанным оюработчикам URL, которые должны будут обрабатывать различные комбинации их этих параметров.
То есть, например, id у хранящейся в базе записи будет всегда, поэтому поле id можно передавать как @PathParam, а например, поля цена, имя, кр. описание или любое другое необязательное к заполнению пользователем поле, которое может быть равно null нужно передавать как @QueryParam. Так как если в URL будет null, то естественно ничего работать не будет, а если в параметрах, то null значения можно обработать на сервере.
Дополнительно о @PathParam и @QueryParam можно почитать тут:
Good job!
ОтветитьУдалить