Re: Spring REST, опциональные параметры
От: Blazkowicz Россия  
Дата: 20.02.17 06:01
Оценка: 3 (1)
Здравствуйте, RolandD, Вы писали:

RD>1)

RD>@RequestMapping(method = RequestMethod.GET, value= "/users")
RD>HttpServletRequest.getParameterMap()
RD>В этом случае, нужно самому писать парсинг параметров. В принципе ок, но можно ли избежать самостоятельного парсинга строк (
RD>HttpServletRequest.getParameterMap() возвращает Map<String, String[]>)? Может можно что-нибудь вызвать для этого?
Та, ну нафиг. В современном Spring это не актуально.

RD>2)

RD>@RequestMapping(method = RequestMethod.GET, value ="/invoices", params = {"userId", "pageNumber", "pageSize"})
RD>@RequestMapping(method = RequestMethod.GET, value ="/invoices", params = {"userId", "addressId", "pageNumber", "pageSize"})
RD>Тогда непонятно, как сделать pageNumber и pageSize опциональными.
Зачем параметры в RequestMapping???

http://stackoverflow.com/questions/22373696/requestparam-in-spring-mvc-handling-optional-parameters
Можно перегрузить методы и замапить на один и тот же путь.
Можно повесить аннотацию на аргумент метода и там указать что этот значение в нём опционально.
Spring REST, опциональные параметры
От: RolandD  
Дата: 20.02.17 03:25
Оценка:
Привет всем,

Как сделать следующее.

Надо поддержать следующее множество запросов:
GET /users?userId=1
GET /users?userId=1&pageNumber=0&pageSize=1000
GET /users?userId=1&addressId=1
GET /users?userId=1&addressId=1&pageNumber=0&pageSize=1000


Причем хотелось бы в своем коде обрабатывать ситуации, что забыли один из pageNumber или pageSize, например:
/users?userId=1&pageSize=1000 (забыли pageNumber)
/users?userId=1&pageNumber=0 (забыли pageSize)

Вижу следующие пути:
1)
@RequestMapping(method = RequestMethod.GET, value= "/users")
HttpServletRequest.getParameterMap()
В этом случае, нужно самому писать парсинг параметров. В принципе ок, но можно ли избежать самостоятельного парсинга строк (
HttpServletRequest.getParameterMap() возвращает Map<String, String[]>)? Может можно что-нибудь вызвать для этого?

2)
@RequestMapping(method = RequestMethod.GET, value ="/invoices", params = {"userId", "pageNumber", "pageSize"})
@RequestMapping(method = RequestMethod.GET, value ="/invoices", params = {"userId", "addressId", "pageNumber", "pageSize"})
Тогда непонятно, как сделать pageNumber и pageSize опциональными.

Заранее спасибо!
Re[2]: Spring REST, опциональные параметры
От: RolandD  
Дата: 24.02.17 03:57
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Здравствуйте, RolandD, Вы писали:


B>http://stackoverflow.com/questions/22373696/requestparam-in-spring-mvc-handling-optional-parameters

B>Можно перегрузить методы и замапить на один и тот же путь.
B>Можно повесить аннотацию на аргумент метода и там указать что этот значение в нём опционально.

Необходимо, чтобы userId и addressId были обязательными, а pageNo и pageSize — опциональными.
В то же время, хотелось бы, чтобы было несколько методов getUsers, каждый из которых обрабатывал бы свою комбинацию параметров.

Если сделать вот так:
@RequestMapping(method = RequestMethod.GET, value ="/users")
@ResponseBody
public List<User> getUsers(@RequestParam(value = "userId") Long userId, 
    @RequestParam(value = "pageNo", required = false) Integer pageNo, 
    @RequestParam(value ="pageSize", required = false) Integer pageSize){
   ...
}

@RequestMapping(method = RequestMethod.GET, value ="/users")
@ResponseBody
public List<User> getUsers(
    @RequestParam(value = "userId") Long userId, 
    @RequestParam(value = "addressId") Long addressId, 
    @RequestParam(value = "pageNo", required = false) Integer pageNo, 
    @RequestParam(value ="pageSize", required = false) Integer pageSize){
   ...
}


То будет вот такое исключение:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'restController' method 

public java.util.List<com.company.User> com.company.controller.RestController.getUsers(java.lang.Long,java.lang.Long,java.lang.Integer,java.lang.Integer)
to {[/users],methods=[GET]}: There is already 'restController' bean method
public java.util.List<com.company.User> com.company.RestController.getUsers(java.lang.Long,java.lang.Integer,java.lang.Integer) mapped.


RD>>2)

RD>>@RequestMapping(method = RequestMethod.GET, value ="/users", params = {"userId", "pageNumber", "pageSize"})
RD>>@RequestMapping(method = RequestMethod.GET, value ="/users", params = {"userId", "addressId", "pageNumber", "pageSize"})
RD>>Тогда непонятно, как сделать pageNumber и pageSize опциональными.
B>Зачем параметры в RequestMapping???

Чтобы победить это, можно сделать вот так:
@RequestMapping(method = RequestMethod.GET, value ="/users", params = {"userId", "pageNo", "pageSize"})
@ResponseBody
public List<User> getUsers(@RequestParam(value = "userId") Long userId, 
    @RequestParam(value = "pageNo", required = false) Integer pageNo, 
    @RequestParam(value ="pageSize", required = false) Integer pageSize){
   ...
}

@RequestMapping(method = RequestMethod.GET, value ="/users", params = {"userId", "addressId", "pageNo", "pageSize"})
@ResponseBody
public List<User> getUsers(
    @RequestParam(value = "userId") Long userId, 
    @RequestParam(value = "addressId") Long addressId, 
    @RequestParam(value = "pageNo", required = false) Integer pageNo, 
    @RequestParam(value ="pageSize", required = false) Integer pageSize){
   ...
}


Тогда запросы
http://localhost:8080/users?userId=1&pageNo=0&&pageSize=10 
http://localhost:8080/users?userId=1&addressId=4&pageNo=0&&pageSize=10

попадают в правильные хэндлеры, однако например (пропускаем необязательные параметры)

http://localhost:8080/users?userId=1&addressId=4


выдаст ошибку
There was an unexpected error (type=Bad Request, status=400).
Parameter conditions "userId, pageNo, pageSize" OR "userId, addressId, pageNo, pageSize" not met for actual request parameters: userId={11242}, addressId={112}


То есть получается два варианта:

1) один мега-метод, у которого есть все параметры (некоторые опциональные) и он сам разбирается, что задано, а что нет. Не подходит, поскольку хотелось бы, чтобы каждый набор параметров обрабатывался в своем методе.
2) много перегруженных методов getUsers с заданной спецификацией params в @RequestMapping. Не подходит, потому что нельзя сделать необязательные параметры.

Не подскажите, как это можно решить?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.