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

后端 未结 3 1896
暗喜
暗喜 2021-02-05 02:36
@RequestMapping(value = \"/contact.html\", method = RequestMethod.POST)
public final ModelAndView contact(
        @RequestParam(value = \"name\", required = false) Opti         


        
相关标签:
3条回答
  • 2021-02-05 03:16

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

    ORIGINAL ANSWER (about Guava's Optional):

    Don't do that, just use String and let Spring handle null in its way.

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

    @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:

    @RequestMapping("foo")
    @ResponseBody
    public String foo(@RequestParam(required = false) final String name) {
      return "name: " + (name == null ? "null" : name);
    }
    
    0 讨论(0)
  • 2021-02-05 03:19

    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:.

    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 is very useful for managing optional parametrers, like errors in Spring.

    0 讨论(0)
  • 2021-02-05 03:19

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

    In Spring HandlerMethodInvoker I found resolveRequestParam method

        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.

    0 讨论(0)
提交回复
热议问题