복붙노트

[SPRING] Ajax를 사용하여 @RequestBody의 여러 변수를 Spring MVC 컨트롤러에 전달

SPRING

Ajax를 사용하여 @RequestBody의 여러 변수를 Spring MVC 컨트롤러에 전달

뒷받침 물건을 감쌀 필요가 있습니까? 나는 이것을 원한다.

@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을 사용하는 것입니다.

해결법

  1. ==============================

    1.당신은 맞습니다. @RequestBody annotated 매개 변수는 요청의 전체 본문을 보유하고 하나의 객체에 바인딩 할 것으로 예상되므로 본질적으로 옵션을 사용해야합니다.

    당신은 맞습니다. @RequestBody annotated 매개 변수는 요청의 전체 본문을 보유하고 하나의 객체에 바인딩 할 것으로 예상되므로 본질적으로 옵션을 사용해야합니다.

    접근 방식을 절대적으로 원한다면 할 수있는 맞춤 구현이 있습니다.

    이것이 당신의 아들이라고 해봅시다.

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

    여기에있는 두 개의 매개 변수에 바인딩하고 싶습니다.

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

    먼저 원하는 정보에 대한 경로와 같은 JSON 경로를 사용하여 @JsonArg와 같이 사용자 정의 주석을 정의합니다.

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

    이제 위에서 정의한 JsonPath를 사용하여 실제 인수를 해결하는 Custom 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 "";
    
        }
    }
    

    이제 스프링 MVC에 등록하십시오. 조금 관련이 있지만 이것은 깔끔하게 작동해야합니다.

  2. ==============================

    2.@RequestBody가 단일 객체에 매핑되어야한다는 것은 사실이지만 해당 객체는 Map이 될 수 있으므로 달성하려는 대상에 대한 좋은 방법을 제공합니다 (하나의 객체를 작성할 필요가 없음).

    @RequestBody가 단일 객체에 매핑되어야한다는 것은 사실이지만 해당 객체는 Map이 될 수 있으므로 달성하려는 대상에 대한 좋은 방법을 제공합니다 (하나의 객체를 작성할 필요가 없음).

    @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"
    
  3. ==============================

    3.보다 간단한 데이터 유형을 위해 body 및 path 변수를 사용하여 post 인수를 혼합 할 수 있습니다.

    보다 간단한 데이터 유형을 위해 body 및 path 변수를 사용하여 post 인수를 혼합 할 수 있습니다.

    @RequestMapping(value = "new-trade/portfolio/{portfolioId}", method = RequestMethod.POST)
        public ResponseEntity<List<String>> newTrade(@RequestBody Trade trade, @PathVariable long portfolioId) {
    ...
    }
    
  4. ==============================

    4.@RequestParam은 클라이언트가 보낸 HTTP GET 또는 POST 매개 변수이며 요청 매핑은 변수의 URL 세그먼트입니다.

    @RequestParam은 클라이언트가 보낸 HTTP GET 또는 POST 매개 변수이며 요청 매핑은 변수의 URL 세그먼트입니다.

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

    var1 & var2는 요청 매개 변수입니다.

    http:/host/form/{params}
    

    {params}는 요청 매핑입니다. http : / host / form / user 또는 http : / host / form / firm과 같이 서비스를 호출 할 수 있습니다. 회사 및 사용자가 경로 변수로 사용됩니다.

  5. ==============================

    5.json을 사용하는 대신 간단한 작업을 수행 할 수 있습니다.

    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";
    }
    

    희망이 당신을 도와줍니다.

  6. ==============================

    6.요청 매개 변수가 GET과 POST 둘 다에 존재하면 가져 오기에서 URL에 쿼리 문자열로 추가되지만 POST의 경우 요청 본문 내에 있습니다

    요청 매개 변수가 GET과 POST 둘 다에 존재하면 가져 오기에서 URL에 쿼리 문자열로 추가되지만 POST의 경우 요청 본문 내에 있습니다

  7. ==============================

    7.나는 Biju의 해결책을 채택했다 :

    나는 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

  8. ==============================

    8.당신이 json을 추가하는 곳이 확실하지는 않지만, 각도로 이것을 좋아한다면 요청없이 작동합니다. Body : 모난:

    당신이 json을 추가하는 곳이 확실하지는 않지만, 각도로 이것을 좋아한다면 요청없이 작동합니다. Body : 모난:

        const params: HttpParams = new HttpParams().set('str1','val1').set('str2', ;val2;);
        return this.http.post<any>( this.urlMatch,  params , { observe: 'response' } );
    

    자바:

    @PostMapping(URL_MATCH)
    public ResponseEntity<Void> match(Long str1, Long str2) {
      log.debug("found: {} and {}", str1, str2);
    }
    
  9. ==============================

    9.좋은. 필요한 필드가 포함 된 값 개체 (Vo)를 만드는 것이 좋습니다. 코드가 더 간단합니다. Jackson의 기능을 변경하지 않으며 이해하기가 더 쉽습니다. 문안 인사!

    좋은. 필요한 필드가 포함 된 값 개체 (Vo)를 만드는 것이 좋습니다. 코드가 더 간단합니다. Jackson의 기능을 변경하지 않으며 이해하기가 더 쉽습니다. 문안 인사!

  10. ==============================

    10.@RequestParam을 사용하여 원하는 것을 얻을 수 있습니다. 이를 위해서는 다음을 수행해야합니다.

    @RequestParam을 사용하여 원하는 것을 얻을 수 있습니다. 이를 위해서는 다음을 수행해야합니다.

    나는 알고있다, 그것의 약간의 해킹 그러나 그것은 일한다! ;)

  11. from https://stackoverflow.com/questions/12893566/passing-multiple-variables-in-requestbody-to-a-spring-mvc-controller-using-ajax by cc-by-sa and MIT license