135

バッキング オブジェクトをラップする必要がありますか? 私はこれをしたい:

@RequestMapping(value = "/Test", method = RequestMethod.POST)
@ResponseBody
public boolean getTest(@RequestBody String str1, @RequestBody String str2) {}

そして、次のような JSON を使用します。

{
    "str1": "test one",
    "str2": "two test"
}

しかし、代わりに私は使用する必要があります:

@RequestMapping(value = "/Test", method = RequestMethod.POST)
@ResponseBody
public boolean getTest(@RequestBody Holder holder) {}

次に、この JSON を使用します。

{
    "holder": {
        "str1": "test one",
        "str2": "two test"
    }
}

あれは正しいですか?私の他のオプションは、をに変更しRequestMethodてクエリ文字列で使用GETするか、いずれかで使用することです。@RequestParam@PathVariableRequestMethod

4

16 に答える 16

114

単一のオブジェクトにマップする必要があるのは事実ですが@RequestBody、そのオブジェクトは である可能性があるMapため、これにより、達成しようとしているものへの良い方法が得られます (1 回限りのバッキング オブジェクトを記述する必要はありません)。

@RequestMapping(value = "/Test", method = RequestMethod.POST)
@ResponseBody
public boolean getTest(@RequestBody Map<String, String> json) {
   //json.get("str1") == "test one"
}

完全な JSON ツリーが必要な場合は、 Jackson のObjectNodeにバインドすることもできます。

public boolean getTest(@RequestBody ObjectNode json) {
   //json.get("str1").asText() == "test one"
于 2015-11-17T05:17:39.270 に答える
107

そうです、@RequestBody 注釈付きパラメーターは、リクエストの本文全体を保持し、1 つのオブジェクトにバインドすることが期待されるため、基本的にオプションを使用する必要があります。

あなたのアプローチが絶対に必要な場合は、カスタム実装があります:

これがあなたのjsonだとしましょう:

{
    "str1": "test one",
    "str2": "two test"
}

そして、ここで 2 つのパラメーターにバインドします。

@RequestMapping(value = "/Test", method = RequestMethod.POST)
public boolean getTest(String str1, String str2)

@JsonArgまず、必要な情報へのパスのような JSON パスを使用して、カスタム アノテーションを定義します。

public boolean getTest(@JsonArg("/str1") String str1, @JsonArg("/str2") String str2)

上記で定義したJsonPathを使用して実際の引数を解決するカスタムHandlerMethodArgumentResolverを作成します。

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.IOUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import com.jayway.jsonpath.JsonPath;

public class JsonPathArgumentResolver implements HandlerMethodArgumentResolver{

    private static final String JSONBODYATTRIBUTE = "JSON_REQUEST_BODY";
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(JsonArg.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        String body = getRequestBody(webRequest);
        String val = JsonPath.read(body, parameter.getMethodAnnotation(JsonArg.class).value());
        return val;
    }

    private String getRequestBody(NativeWebRequest webRequest){
        HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
        String jsonBody = (String) servletRequest.getAttribute(JSONBODYATTRIBUTE);
        if (jsonBody==null){
            try {
                String body = IOUtils.toString(servletRequest.getInputStream());
                servletRequest.setAttribute(JSONBODYATTRIBUTE, body);
                return body;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return "";

    }
}

これをSpring MVCに登録するだけです。少し複雑ですが、これは問題なく動作するはずです。

于 2012-10-15T14:19:32.510 に答える
12

より単純なデータ型の body 変数と path 変数を使用して、post 引数を混同できます。

@RequestMapping(value = "new-trade/portfolio/{portfolioId}", method = RequestMethod.POST)
    public ResponseEntity<List<String>> newTrade(@RequestBody Trade trade, @PathVariable long portfolioId) {
...
}
于 2016-05-09T18:30:53.283 に答える
2

@RequestParamはクライアントから送信されたHTTP GETorPOSTパラメータです。リクエスト マッピングは変数の URL のセグメントです。

http:/host/form_edit?param1=val1&param2=val2

var1&var2はリクエスト パラメータです。

http:/host/form/{params}

{params}リクエストマッピングです。のようにサービスを呼び出すことができます :http:/host/form/userまたはhttp:/host/form/firm 会社とユーザーがとして使用されている場所Pathvariable

于 2012-10-15T10:44:53.487 に答える
1

json を使用する代わりに、簡単なことを行うことができます。

$.post("${pageContext.servletContext.contextPath}/Test",
                {
                "str1": "test one",
                "str2": "two test",

                        <other form data>
                },
                function(j)
                {
                        <j is the string you will return from the controller function.>
                });

コントローラーで、次のように ajax リクエストをマップする必要があります。

 @RequestMapping(value="/Test", method=RequestMethod.POST)
    @ResponseBody
    public String calculateTestData(@RequestParam("str1") String str1, @RequestParam("str2") String str2, HttpServletRequest request, HttpServletResponse response){
            <perform the task here and return the String result.>

            return "xyz";
}

これがお役に立てば幸いです。

于 2012-10-15T12:15:44.823 に答える
0

リクエスト パラメータは GET と POST の両方に存在します。Get の場合はクエリ文字列として URL に追加されますが、POST の場合はリクエスト ボディ内にあります。

于 2013-06-16T18:14:58.050 に答える