Передача нескольких переменных в @RequestBody controllerу Spring MVC с использованием Ajax

Нужно ли обертывать вспомогательный объект? Я хочу сделать это:

@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 с помощью @PathVariable RequestMethod .

Вы правы, ожидается, что аннотированный параметр @RequestBody будет удерживать весь объект запроса и привязываться к одному объекту, поэтому вам по существу придется идти с вашими опциями.

Если вы абсолютно хотите, чтобы ваш подход, есть пользовательская реализация, которую вы можете сделать:

Скажите, что это ваш json:

 { "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) 

Теперь напишите Custom HandlerMethodArgumentResolver, который использует описанный выше JsonPath для разрешения фактического аргумента:

 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 json) { //json.get("str1") == "test one" } 

Вы также можете привязать объект ObjectNode к jacksonу, если хотите полное дерево JSON:

 public boolean getTest(@RequestBody ObjectNode json) { //json.get("str1").asText() == "test one" 

Вы можете смешать аргумент post, используя переменную body и path для более простых типов данных:

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

@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 где фирма и пользователь используются как Pathvariable .

Вместо использования json вы можете сделать простую вещь.

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

Теперь в controllerе вам нужно сопоставить запрос ajax, как показано ниже:

  @RequestMapping(value="/Test", method=RequestMethod.POST) @ResponseBody public String calculateTestData(@RequestParam("str1") String str1, @RequestParam("str2") String str2, HttpServletRequest request, HttpServletResponse response){  return "xyz"; } 

Надеюсь, это вам поможет.

параметр запроса существует как для 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; } } 

Что другое:

  • Я использую Jackson для преобразования json
  • Мне не нужно значение в annotations, вы можете прочитать имя параметра из метода MethodParameter
  • Я также читаю тип параметра из Methodparameter =>, поэтому решение должно быть общим (я тестировал его со строкой и DTO)

BR

Не уверен, где вы добавляете json, но если я делаю это так, то с угловым он работает без requestBody: angluar:

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

Ява:

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

Хорошо. Я предлагаю создать объект Value (Vo), который содержит нужные вам поля. Код проще, мы не меняем работу jacksonа, и это еще проще понять. С уважением!

Вы можете достичь того, чего хотите, используя @RequestParam . Для этого вы должны сделать следующее:

  1. Объявите параметры RequestParams, которые представляют ваши объекты, и установите required опцию в значение false, если вы хотите иметь возможность отправить нулевое значение.
  2. На интерфейсе стройте объекты, которые вы хотите отправить, и включайте их в качестве параметров запроса.
  3. На бэкэнде переверните JSON обратно в объекты, которые они представляют, используя Jackson ObjectMapper или что-то в этом роде, и вуаля!

Я знаю, его немного взломать, но он работает! 😉

  • Spring web, security + web.xml + mvc dispatcher + Bean создается дважды
  • Как включить js и CSS в JSP с помощью Spring MVC
  • Как загрузить файл с сервера с помощью jQuery AJAX и Spring MVC 3
  • Поиск URL вашего приложения только с помощью ServletContext
  • Как работает автомастер весной?
  • Spring MVC - Как получить все параметры запроса на карте в controllerе Spring?
  • При использовании Spring Security, каков правильный способ получить текущее имя пользователя (например, SecurityContext) в компоненте?
  • Перенаправление на Ajax Jquery Call
  • Как ответить с ошибкой HTTP 400 в методе Spring MVC @ResponseBody, возвращающем String?
  • Аутентификация RESTful через Spring
  • Spring WebSocket @SendToSession: отправить сообщение на определенный сеанс
  • Давайте будем гением компьютера.