Как @RequestParam в Spring обрабатывает Guava Необязательно?
@RequestMapping(value = "/contact.html", method = RequestMethod.POST)
public final ModelAndView contact(
@RequestParam(value = "name", required = false) Optional<String> name) {
Как Spring @RequestMapping
обрабатывает Optional
из Guava library, если значение параметра не требуется и ничего не отправлено?
Будет ли это:
- Установите
null
- Установите
Optional.absent()
Может ли Optional.fromNullable(T)
использоваться для принятия запроса?
Ответы
Ответ 1
EDIT (октябрь 2015 г.): Spring 4 обрабатывает java.util.Optional
(из Java 8) из коробки и гарантирует, что Optional
сам не является нулевым, но исходный вопрос был о Guava com.google.common.base.Optional
, использование которого в качестве @RequestParam
сильно обескуражено в этом конкретном случае (потому что оно может быть нулевым).
ОРИГИНАЛЬНЫЙ ОТВЕТ (о Guava Optional
):
Не делайте этого, просто используйте String
и пусть Spring обрабатывает null
.
Optional<T>
предполагается использовать как возвращаемое значение и редко как параметр. В этом конкретном случае Spring отображает отсутствующий параметр "name"
на null
, поэтому даже если после реализации специального редактора свойств вы закончите с помощью null
проверить:
@RequestMapping("foo")
@ResponseBody
public String foo(@RequestParam(required = false) final Optional name) {
return "name: " + (name == null ? "null" : name.get());
}
что совершенно не нужно (и missuses Optional
), потому что это может быть достигнуто с помощью
@RequestMapping("foo")
@ResponseBody
public String foo(@RequestParam(required = false) final String name) {
return "name: " + (name == null ? "null" : name);
}
Ответ 2
Я рекомендую использовать версию Java 8: java.util.Optional
. Посмотрите документацию Oracle в http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html.
Также укажите имя переменной, особенно если вы используете Spring 3 или выше:.
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class LoginController
{
private static final Logger LOGGER = LoggerFactory.getLogger(LoginController.class);
@RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView getLoginPage(@RequestParam(name = "error", required = false) Optional<String> errorMsg)
{
//error.ifPresent(LOGGER::debug); //Java 8 with Optional
return new ModelAndView("login", "error", errorMsg);
}
}
java.util.Optional
очень полезен для управления необязательными параметрами, такими как ошибки в Spring.
Ответ 3
Ответ на ваш вопрос будет необязательным параметром, который сначала устанавливает значение null.
В Spring HandlerMethodInvoker я нашел метод resolveRequestParam
Object paramValue = null;
...
if (multipartRequest != null) {
...
// Check if this is multipart request and set paramValue in this case.
}
// Otherwise
if (paramValue == null) {
String[] paramValues = webRequest.getParameterValues(paramName);
if (paramValues != null) {
paramValue = (paramValues.length == 1 ? paramValues[0] : paramValues);
}
}
if (paramValue == null) {
if (defaultValue != null) {
paramValue = resolveDefaultValue(defaultValue);
}
else if (required) {
raiseMissingParameterException(paramName, paramType);
}
...
}
...
Итак, сначала мы проверяем, является ли это многостраничным запросом. В противном случае мы получаем значения параметров по имени параметра из запроса сервлета. Наконец, если значение параметра null проверяется, требуется ли параметр. Если требуется, мы генерируем исключение, иначе возвращаем null.