バッキングオブジェクトでラップする必要がありますか?私はこれをやりたい:
@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
を使用するか、RequestMethod
で@PathVariable
を使用することです。
正しいです。@ 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に登録するだけです。少し複雑ですが、これはきれいに機能するはずです。
@RequestBody
は単一のオブジェクトにマップする必要があるのは事実ですが、そのオブジェクトはMap
になる可能性があるため、これは達成しようとしているものへの良い方法を提供しますオブジェクト):
@RequestMapping(value = "/Test", method = RequestMethod.POST)
@ResponseBody
public boolean getTest(@RequestBody Map<String, String> json) {
//json.get("str1") == "test one"
}
完全なJSONツリーが必要な場合は、ジャクソンの ObjectNode にバインドすることもできます。
public boolean getTest(@RequestBody ObjectNode json) {
//json.get("str1").asText() == "test one"
単純なデータ型のbody変数とpath変数を使用して、post引数を混在させることができます。
@RequestMapping(value = "new-trade/portfolio/{portfolioId}", method = RequestMethod.POST)
public ResponseEntity<List<String>> newTrade(@RequestBody Trade trade, @PathVariable long portfolioId) {
...
}
複数のオブジェクト、パラメーター、変数などを渡すため。パラメータとしてjacksonライブラリのObjectNodeを使用して動的に実行できます。次のようにできます:
@RequestMapping(value = "/Test", method = RequestMethod.POST)
@ResponseBody
public boolean getTest(@RequestBody ObjectNode objectNode) {
// And then you can call parameters from objectNode
String strOne = objectNode.get("str1").asText();
String strTwo = objectNode.get("str2").asText();
// When you using ObjectNode, you can pas other data such as:
// instance object, array list, nested object, etc.
}
これが役立つことを願っています。
@RequestParam
は、クライアントから送信されるHTTP GET
またはPOST
パラメーターです。リクエストマッピングは、変数のURLのセグメントです。
http:/Host/form_edit?param1=val1¶m2=val2
var1
&var2
はリクエストのパラメーターです。
http:/Host/form/{params}
{params}
はリクエストのマッピングです。次のようにサービスを呼び出すことができます:http:/Host/form/user
またはhttp:/Host/form/firm
会社とユーザーはPathvariable
として使用されます。
@RequestParam
を使用して、目的を達成できます。このためには、次のことを行う必要があります。
required
オプションをfalseに設定します。ちょっとしたハックですが、動作します! ;)
Jsonを追加する場所がわかりませんが、angularでこのようにすると、requestBody:angluarがなくても機能します。
const params: HttpParams = new HttpParams().set('str1','val1').set('str2', ;val2;);
return this.http.post<any>( this.urlMatch, params , { observe: 'response' } );
Java:
@PostMapping(URL_MATCH)
public ResponseEntity<Void> match(Long str1, Long str2) {
log.debug("found: {} and {}", str1, str2);
}
良い。必要なフィールドを含む値オブジェクト(Vo)を作成することをお勧めします。コードは単純で、Jacksonの機能を変更せず、さらに理解しやすくなっています。よろしく!
@RequestBody Map<String, String> params
を使用してから、params.get("key")
を使用してパラメーターの値を取得することもできます。
gETとPOSTの両方にリクエストパラメータが存在します。Getの場合、クエリ文字列としてURLに追加されますが、POSTの場合はリクエスト本文内にあります。
私はBijuのソリューションを適応させました:
import Java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.Apache.commons.io.IOUtils;
import org.springframework.core.MethodParameter;
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.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonPathArgumentResolver implements HandlerMethodArgumentResolver{
private static final String JSONBODYATTRIBUTE = "JSON_REQUEST_BODY";
private ObjectMapper om = new ObjectMapper();
@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 jsonBody = getRequestBody(webRequest);
JsonNode rootNode = om.readTree(jsonBody);
JsonNode node = rootNode.path(parameter.getParameterName());
return om.readValue(node.toString(), parameter.getParameterType());
}
private String getRequestBody(NativeWebRequest webRequest){
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
String jsonBody = (String) webRequest.getAttribute(JSONBODYATTRIBUTE, NativeWebRequest.SCOPE_REQUEST);
if (jsonBody==null){
try {
jsonBody = IOUtils.toString(servletRequest.getInputStream());
webRequest.setAttribute(JSONBODYATTRIBUTE, jsonBody, NativeWebRequest.SCOPE_REQUEST);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return jsonBody;
}
}
違いは何ですか:
BR
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";
}
これがお役に立てば幸いです。