web-dev-qa-db-ja.com

Springの@RequestParamはGuavaのOptionalをどのように処理しますか?

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

パラメーター値が不要で何も送信されない場合、Springの_@RequestMapping_は Optional from Guava library をどのように処理しますか?

それになります:

  • nullに設定
  • Optional.absent()に設定

Optional.fromNullable(T)を使用して要求を受け入れることはできますか?

29
Anders

EDIT(2015年10月):Spring 4は_Java.util.Optional_を処理します(from Java 8)すぐに使用可能およびOptional自体がnullではないことを保証が、元の質問はGuavaの_com.google.common.base.Optional_に関するものであり、この特定のケースでは_@RequestParam_としての使用は非常に推奨されません(なぜならcanはnullです)。

オリジナルの回答(グアバの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());
}
_

これは完全に不必要です(Optionalを誤用しています)。

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

Java 8バージョン:Java.util.Optionalhttp://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.Optionalは、Springのerrorsのように、オプションのパラメータを管理するのに非常に便利です。

4
EliuX

あなたの質問に対する答えは、オプションのパラメータになります最初に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を返します。

0
mvb13