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 .

0voto

vinga Points 521

Si quelqu'un est intéressé par la solution webflux, voici une version réactive, basée sur la réponse de Biju.

Veuillez noter qu'il y a un morceau très petit mais synchronisé, nécessaire pour protéger le corps d'être consommé plus d'une fois. Si vous préférez une version complètement non-bloquante, je suggère de publier le flux qui obtient json sur le même scheduler, pour rendre la vérification et la lecture séquentielles.

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.web.reactive.BindingContext;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

@Slf4j
@RequiredArgsConstructor
public class JsonArgumentResolver implements HandlerMethodArgumentResolver {
    private static final String ATTRIBUTE_KEY = "BODY_TOSTRING_RESOLVER";
    private final ObjectMapper objectMapper;

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(JsonArgument.class);
    }

    @Override
    public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,
                                        ServerWebExchange exchange) {
        String fieldName = parameter.getParameterName();
        Class<?> clz = parameter.getParameterType();

        return getRequestBody(exchange).map(body -> {
            try {
                JsonNode jsonNode = objectMapper.readTree(body).get(fieldName);
                String s = jsonNode.toString();
                return objectMapper.readValue(s, clz);
            } catch (JsonProcessingException e) {
                log.error(e.getMessage(), e);
                throw new RuntimeException(e);
            }
        });
    }

    private Mono<String> getRequestBody(ServerWebExchange exchange) {
        Mono<String> bodyReceiver;
        synchronized (exchange) {
            bodyReceiver = exchange.getAttribute(ATTRIBUTE_KEY);
            if (bodyReceiver == null) {
                bodyReceiver = exchange.getRequest().getBody()
                        .map(this::convertToString)
                        .single()
                        .cache();
                exchange.getAttributes().put(ATTRIBUTE_KEY, bodyReceiver);
            }
        }
        return bodyReceiver;
    }

    private String convertToString(DataBuffer dataBuffer) {
        byte[] bytes = new byte[dataBuffer.readableByteCount()];
        dataBuffer.read(bytes);
        DataBufferUtils.release(dataBuffer);
        return new String(bytes, StandardCharsets.UTF_8);
    }
}

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