spring Spring中@RequestParam如何处理Guava的Optional?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20237796/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 06:22:50  来源:igfitidea点击:

How does @RequestParam in Spring handle Guava's Optional?

springspring-mvcguavanullableoptional

提问by Anders

@RequestMapping(value = "/contact.html", method = RequestMethod.POST)
public final ModelAndView contact(
        @RequestParam(value = "name", required = false) Optional<String> name) {

How does Spring's @RequestMappinghandle an Optionalfrom Guava libraryif the parameter value is not required and nothing is sent?

如果不需要参数值并且不发送任何内容,Spring 如何@RequestMapping处理Optional来自Guava 库的an ?

Will it be:

那将会:

  • Set to null
  • Set to Optional.absent()
  • 设置 null
  • 设置 Optional.absent()

Can Optional.fromNullable(T)be used to accept the request?

可以Optional.fromNullable(T)用来接受请求吗?

回答by Xaerxess

EDIT (October 2015):Spring 4 handles java.util.Optional(from Java 8) out of the box and guarantees that Optionalitself is not null, but original question was about Guava's com.google.common.base.Optionalwhich usage as @RequestParamis highly discouraged in this specific case (because it canbe null).

编辑(2015 年 10 月):Spring 4 处理java.util.Optional(来自 Java 8)开箱即用,并保证它Optional本身不是 null,但最初的问题是关于 Guava在这种特定情况下的com.google.common.base.Optional使用@RequestParam非常不鼓励(因为它可以为 null)。

ORIGINAL ANSWER(about Guava's Optional):

原始答案(关于番石榴的Optional):

Don't do that, just use Stringand let Spring handle nullin its way.

不要那样做,只需使用String并让 Springnull以它的方式处理。

Optional<T>is supposed to be used as return valueand rarely as a parameter. In this particular case Spring will map missing "name"parameter to null, so even if after implementing custom property editoryou'll finish with nullcheck:

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());
}

which is completely unnecessary (and missuses Optional), because it can be achieved with:

这是完全没有必要的(和误用Optional),因为它可以通过以下方式实现:

@RequestMapping("foo")
@ResponseBody
public String foo(@RequestParam(required = false) final String name) {
  return "name: " + (name == null ? "null" : name);
}

回答by EliuX

I recommend to use the Java 8 version: java.util.Optional. Look at the Oracle documentation in http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html. Also put a name to the variable, specially if your using Spring 3 or higher:.

我建议使用 Java 8 版本:java.util.Optional. 查看http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html中的 Oracle 文档。还要为变量命名,特别是如果您使用 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.Optionalis very useful for managing optional parametrers, like errorsin Spring.

java.util.Optional对于管理可选参数非常有用,例如Spring 中的错误

回答by mvb13

The answer on you question will be optional parameter first is setting to null.

您问题的答案将是可选参数,首先设置为 null。

In Spring HandlerMethodInvoker I found resolveRequestParam method

在 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);
        }
        ...
     }
     ...

So first we check if it is a multipart request. Otherwise we get parameters values by parameter name from servlet request. Finally if parameter value null we check if parameter is required. If required we throw exception, otherwise return null.

所以首先我们检查它是否是一个多部分请求。否则,我们从 servlet 请求中通过参数名称获取参数值。最后,如果参数值为 null,我们检查是否需要参数。如果需要,我们抛出异常,否则返回 null。