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 ir con sus opciones.
Sin embargo, si desea absolutamente su enfoque, existe 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 HandlerMethodArgumentResolver personalizado 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 registre esto con Spring MVC. Un poco complicado, pero esto debería funcionar limpiamente.
@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface JsonArg { String value() default ""; }Si bien es cierto que
@RequestBodydebe asignarse a un solo objeto, ese objeto puede ser unMap, por lo que esto le brinda una buena forma de lo que está intentando lograr (no es necesario escribir un objeto de respaldo único):También puede enlazar al ObjectNode de Jackson si desea un árbol JSON completo:
fuente
Mapobjeto para almacenar cualquier cantidad de objetos dentro de él, pero el objeto de nivel superior debe ser solo uno, no puede haber dos objetos de nivel superior.Map<String, String>es: las bibliotecas de documentación de API (swagger / springfox, etc.) probablemente no podrán analizar su esquema de solicitud / respuesta desde su código fuente.Puede mezclar el argumento de publicación utilizando la variable body y path para tipos de datos más simples:
fuente
Para pasar varios objetos, parámetros, variables, etc. Puede hacerlo dinámicamente usando ObjectNode de la biblioteca jackson como su parámetro. Puedes hacerlo así:
Espero esta ayuda.
fuente
@RequestParames el parámetroHTTP GEToPOSTenviado por el cliente, el mapeo de solicitud es un segmento de URL cuya variable:var1yvar2son parámetros de solicitud.{params}es un mapeo de solicitudes. puede llamar a su servicio como:http:/host/form/userohttp:/host/form/firmdonde se utilizan firmas y usuarios comoPathvariable.fuente
La solución fácil es crear una clase de carga útil que tenga str1 y str2 como atributos:
Y después de que puedas pasar
y el cuerpo de su solicitud es:
fuente
En lugar de usar json, puede hacer cosas simples.
Ahora, en el controlador, debe mapear la solicitud ajax de la siguiente manera:
Espero que esto te ayude.
fuente
He adaptado la solución de Biju:
¿Cuál es la diferencia?
BR
fuente
El parámetro de solicitud existe tanto para GET como para POST, para Get se agregará como cadena de consulta a la URL, pero para POST está dentro del Cuerpo de la solicitud
fuente
No estoy seguro de dónde agrega el json, pero si lo hago así con angular, funciona sin el requestBody: angluar:
Java:
fuente
Bueno. Sugiero crear un objeto de valor (Vo) que contenga los campos que necesita. El código es más sencillo, no cambiamos el funcionamiento de Jackson y es aún más fácil de entender. ¡Saludos!
fuente
Puedes lograr lo que quieras usando
@RequestParam. Para ello debes hacer lo siguiente:requiredopción en falso si desea poder enviar un valor nulo.Lo sé, es un truco pero funciona. ;)
fuente
también puede
@RequestBody Map<String, String> paramsusarlo, luego usarloparams.get("key")para obtener el valor del parámetrofuente
También puede usar un mapa de MultiValue para mantener el requestBody adentro. Aquí está el ejemplo.
a diferencia de la anotación @RequestBody cuando usamos un mapa para contener el cuerpo de la solicitud, necesitamos anotar con @RequestParam
y enviar al usuario en Json RequestBody
fuente