Saltar al contenido

Pasar múltiples variables en @RequestBody a un controlador Spring MVC usando Ajax

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 @JsonArgcon 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 Mappor 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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *