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
" " " 를 합니다.@PathVariable
쪽인가로RequestMethod
while while while while while while while while while@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"
맞습니다. @RequestBody 주석이 달린 파라미터는 요청 본문 전체를 유지하고 하나의 오브젝트에 바인드하기 때문에 기본적으로 옵션을 사용해야 합니다.
꼭 필요한 경우 커스텀 구현이 가능합니다.
이게 네 아들이라고 해:
{
"str1": "test one",
"str2": "two test"
}
이 두 개의 파라미터에 바인드합니다.
@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를 사용하여 실제 인수를 해결하는 커스텀 핸들러 MethodArgumentResolver를 작성합니다.
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에 등록해 주세요. 조금 관련이 있지만, 이 작업은 깔끔하게 작동할 것입니다.
다중 객체, 매개 변수 등을 전달하기 위한 것입니다.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.
}
이게 도움이 됐으면 좋겠어요.
간단한 데이터 유형에 대해 body 변수와 path 변수를 사용하여 post 인수를 혼재시킬 수 있습니다.
@RequestMapping(value = "new-trade/portfolio/{portfolioId}", method = RequestMethod.POST)
public ResponseEntity<List<String>> newTrade(@RequestBody Trade trade, @PathVariable long portfolioId) {
...
}
간단한 해결책은 str1과 str2를 속성으로 하는 페이로드 클래스를 만드는 것입니다.
@Getter
@Setter
public class ObjHolder{
String str1;
String str2;
}
그리고 네가 합격하고 나면
@RequestMapping(value = "/Test", method = RequestMethod.POST)
@ResponseBody
public boolean getTest(@RequestBody ObjHolder Str) {}
요청 내용은 다음과 같습니다.
{
"str1": "test one",
"str2": "two test"
}
@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
firm & 는 firm & user로 됩니다.Pathvariable
.
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";
}
도움이 되시길 바랍니다.
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;
}
}
차이점:
- 잭슨을 이용해서 json을 개종시키고 있어
- 주석의 값은 필요 없습니다. MethodParameter에서 파라미터의 이름을 읽을 수 있습니다.
- Method parameter = >에서 파라미터의 타입도 읽어냈기 때문에 솔루션은 범용이어야 합니다(문자열과 DTO로 테스트했습니다).
BR
다중값 맵을 사용하여 requestBody를 유지할 수도 있습니다.여기에 그 예가 있다.
foosId -> pathVariable
user -> extracted from the Map of request Body
맵을 사용하여 요청 본문을 유지할 때 @RequestBody 주석과는 달리 @RequestParam으로 주석을 달아야 합니다.
Json Request Body로 사용자를 전송합니다.
@RequestMapping(value = "v1/test/foos/{foosId}", method = RequestMethod.POST, headers = "Accept=application"
+ "/json",
consumes = MediaType.APPLICATION_JSON_UTF8_VALUE ,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String postFoos(@PathVariable final Map<String, String> pathParam,
@RequestParam final MultiValueMap<String, String> requestBody) {
return "Post some Foos " + pathParam.get("foosId") + " " + requestBody.get("user");
}
GET와 POST 모두에 대해 request 파라미터가 존재합니다.Get의 경우 URL에 쿼리 문자열로 추가되지만 POST의 경우 Request Body 내에 있습니다.
json을 어디에 추가할지는 모르겠지만, 각도로 이렇게 하면 요청 없이 작동합니다.본문: angluar:
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);
}
좋습니다. 필요한 필드를 포함하는 값 개체(Vo)를 만드는 것이 좋습니다.코드는 더 단순하고, 우리는 잭슨의 기능을 바꾸지 않으며, 더 쉽게 이해할 수 있습니다.안부 전해 주세요!
다음을 사용하여 원하는 것을 달성할 수 있습니다.@RequestParam
이를 위해서는 다음 작업을 수행해야 합니다.
- 개체를 나타내는 RequestParams 파라미터를 선언하고
required
null 값을 송신할 수 있는 경우 옵션을 false로 설정합니다. - 프런트 엔드에서는 송신할 오브젝트를 문자열화하여 요청 파라미터로 포함합니다.
- 백엔드에서 JSON 문자열은 Jackson Object Mapper 같은 것을 사용하여 나타내는 객체로 되돌리고 voila!
알아, 좀 엉터리지만 잘 돼!;)
사용자도 가능합니다.@RequestBody Map<String, String> params
, 그 후 를 사용합니다.params.get("key")
파라미터의 값을 취득하다
내부 클래스 사용
@RestController
public class MyController {
@PutMapping("/do-thing")
public void updateFindings(@RequestBody Bodies.DoThing body) {
...
}
private static class Bodies {
public static class DoThing {
public String name;
public List<String> listOfThings;
}
}
}
Webflux 솔루션에 관심이 있는 경우 Biju의 답변을 바탕으로 한 반응형 버전을 아래에 나타냅니다.
본체가 두 번 이상 소비되지 않도록 보호하는 데 필요한 매우 작지만 동기화된 청크가 하나 있습니다.만약 당신이 완전 논블로킹 버전을 선호한다면, 나는 체크와 읽기를 순차적으로 하기 위해 같은 스케줄러에 json을 얻는 플럭스를 게시할 것을 제안한다.
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.web.reactive.BindingContext;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
@Slf4j
@RequiredArgsConstructor
public class JsonArgumentResolver implements HandlerMethodArgumentResolver {
private static final String ATTRIBUTE_KEY = "BODY_TOSTRING_RESOLVER";
private final ObjectMapper objectMapper;
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(JsonArgument.class);
}
@Override
public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,
ServerWebExchange exchange) {
String fieldName = parameter.getParameterName();
Class<?> clz = parameter.getParameterType();
return getRequestBody(exchange).map(body -> {
try {
JsonNode jsonNode = objectMapper.readTree(body).get(fieldName);
String s = jsonNode.toString();
return objectMapper.readValue(s, clz);
} catch (JsonProcessingException e) {
log.error(e.getMessage(), e);
throw new RuntimeException(e);
}
});
}
private Mono<String> getRequestBody(ServerWebExchange exchange) {
Mono<String> bodyReceiver;
synchronized (exchange) {
bodyReceiver = exchange.getAttribute(ATTRIBUTE_KEY);
if (bodyReceiver == null) {
bodyReceiver = exchange.getRequest().getBody()
.map(this::convertToString)
.single()
.cache();
exchange.getAttributes().put(ATTRIBUTE_KEY, bodyReceiver);
}
}
return bodyReceiver;
}
private String convertToString(DataBuffer dataBuffer) {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
DataBufferUtils.release(dataBuffer);
return new String(bytes, StandardCharsets.UTF_8);
}
}
언급URL : https://stackoverflow.com/questions/12893566/passing-multiple-variables-in-requestbody-to-a-spring-mvc-controller-using-ajax
'programing' 카테고리의 다른 글
올바른 결과를 반환하지 않음으로써 그룹이 포함된 MySQL 수 (0) | 2023.01.08 |
---|---|
ALTER TABLE Add Column에 시간이 오래 걸립니다. (0) | 2022.12.24 |
소스 파일을 더 이상 사용할 수 없습니다. (0) | 2022.12.24 |
Java의 DAO(Data Access Object) (0) | 2022.12.24 |
2003: '127.0.0.1:3306'에서 MySQL 서버에 연결할 수 없음(99 요청된 주소를 할당할 수 없음) (0) | 2022.12.24 |