Nuestros programadores estrellas agotaron sus depósitos de café, por su búsqueda a tiempo completo por la solución, hasta que Sebastián encontró la respuesta en GitLab y hoy la comparte aquí.
Solución:
Tiene razón, se espera que el parámetro anotado @RequestBody contenga todo el cuerpo de la solicitud y se vincule a un objeto, por lo que esencialmente tendrá que elegir sus opciones.
Si absolutamente desea su enfoque, hay una implementación personalizada que puede hacer:
Di que este es tu json:
"str1": "test one",
"str2": "two test"
y desea vincularlo a los dos parámetros aquí:
@RequestMapping(value = "/Test", method = RequestMethod.POST)
public boolean getTest(String str1, String str2)
Primero defina una anotación personalizada, digamos @JsonArg
con la ruta JSON como ruta a la información que desea:
public boolean getTest(@JsonArg("/str1") String str1, @JsonArg("/str2") String str2)
Ahora escriba un Custom HandlerMethodArgumentResolver que use el JsonPath definido anteriormente para resolver el argumento real:
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 "";
Ahora solo registra esto con Spring MVC. Un poco complicado, pero esto debería funcionar limpiamente.
mientras es true ese @RequestBody
debe mapear a un solo objeto, ese objeto puede ser un Map
por lo que esto le brinda una buena manera de lo que está tratando de lograr (no es necesario escribir un objeto de respaldo único):
@RequestMapping(value = "/Test", method = RequestMethod.POST)
@ResponseBody
public boolean getTest(@RequestBody Map json)
//json.get("str1") == "test one"
También puede vincular a ObjectNode de Jackson si desea un árbol JSON completo:
public boolean getTest(@RequestBody ObjectNode json) {
//json.get("str1").asText() == "test one"
Puede mezclar el argumento de la publicación utilizando el cuerpo y la variable de ruta para tipos de datos más simples:
@RequestMapping(value = "new-trade/portfolio/portfolioId", method = RequestMethod.POST)
public ResponseEntity> newTrade(@RequestBody Trade trade, @PathVariable long portfolioId)
...
Comentarios y calificaciones de la guía
Si para ti ha sido provechoso este artículo, sería de mucha ayuda si lo compartieras con más desarrolladores de esta manera contrubuyes a difundir esta información.