152 votes

Passage de plusieurs variables dans @RequestBody à un contrôleur Spring MVC en utilisant Ajax

Est-il nécessaire d'envelopper dans un objet de soutien ? Je veux faire ceci :

@RequestMapping(value = "/Test", method = RequestMethod.POST)
@ResponseBody
public boolean getTest(@RequestBody String str1, @RequestBody String str2) {}

Et utiliser un JSON comme ceci :

{
    "str1": "test one",
    "str2": "two test"
}

Mais à la place, je dois utiliser :

@RequestMapping(value = "/Test", method = RequestMethod.POST)
@ResponseBody
public boolean getTest(@RequestBody Holder holder) {}

Et ensuite utiliser ce JSON :

{
    "holder": {
        "str1": "test one",
        "str2": "two test"
    }
}

Est-ce exact ? L'autre option serait de modifier le RequestMethod a GET et utiliser @RequestParam dans la chaîne de requête ou utiliser @PathVariable avec soit RequestMethod .

2voto

psisodia Points 1037

@RequestParam es el HTTP GET o POST envoyé par le client, le mapping de la demande est un segment de l'URL qui est variable :

http:/host/form_edit?param1=val1&param2=val2

var1 & var2 sont des paramètres de la demande.

http:/host/form/{params}

{params} est un mappage de requête. Vous pourriez appeler votre service comme : http:/host/form/user o http:/host/form/firm où l'entreprise et l'utilisateur sont utilisés comme Pathvariable .

1voto

Japs Points 2964

Au lieu d'utiliser json, vous pouvez faire une chose simple.

$.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.>
                });

Maintenant, dans le contrôleur, vous devez mapper la requête ajax comme ci-dessous :

 @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";
}

J'espère que cela vous aidera.

1voto

user3227576 Points 259

J'ai adapté la solution de 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;

    }

}

Quelle est la différence ?

  • J'utilise Jackson pour convertir le json
  • Je n'ai pas besoin d'une valeur dans l'annotation. dans le paramètre MethodParameter
  • J'ai également lu le type du paramètre dans le Methodparameter => la solution devrait donc être générique (je l'ai testée avec des chaînes de caractères et des DTO).

BR

1voto

tibi Points 143

Je ne sais pas où vous ajoutez le json mais si je le fais comme ça avec angular, cela fonctionne sans le requestBody : angluar :

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

java :

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

1voto

anayagam Points 81

Vous pouvez également utiliser une MultiValue Map pour contenir le requestBody. En voici l'exemple.

    foosId -> pathVariable
    user -> extracted from the Map of request Body 

Contrairement à l'annotation @RequestBody, lorsqu'on utilise une Map pour contenir le corps de la requête, il faut l'annoter avec @RequestParam.

et envoyer l'utilisateur dans le corps de la requête Json.

  @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");
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X