Подтвердить что ты не робот

Как @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) использоваться для принятия запроса?

4b9b3361

Ответ 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.