Vous avez raison, le paramètre annoté @RequestBody devrait contenir tout le corps de la requête et se lier à un objet, vous devrez donc essentiellement choisir vos options.
Si vous voulez absolument votre approche, il existe une implémentation personnalisée que vous pouvez faire:
Dites que c'est votre json:
{
"str1": "test one",
"str2": "two test"
}
et vous voulez le lier aux deux paramètres ici:
@RequestMapping(value = "/Test", method = RequestMethod.POST)
public boolean getTest(String str1, String str2)
Définissez d'abord une annotation personnalisée, par exemple @JsonArg
, avec le chemin JSON comme le chemin vers les informations souhaitées:
public boolean getTest(@JsonArg("/str1") String str1, @JsonArg("/str2") String str2)
Maintenant, écrivez un HandlerMethodArgumentResolver personnalisé qui utilise le JsonPath défini ci-dessus pour résoudre l'argument réel:
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 "";
}
}
Maintenant, enregistrez-le simplement avec Spring MVC. Un peu impliqué, mais cela devrait fonctionner proprement.
@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface JsonArg { String value() default ""; }
S'il est vrai qu'il
@RequestBody
doit correspondre à un seul objet, cet objet peut être unMap
, donc cela vous donne un bon moyen d'atteindre ce que vous essayez d'atteindre (pas besoin d'écrire un objet de sauvegarde unique):Vous pouvez également vous lier à ObjectNode de Jackson si vous voulez une arborescence JSON complète:
la source
Map
objet pour stocker n'importe quel nombre d'objets à l'intérieur, mais l'objet de niveau supérieur doit toujours être un seul, il ne peut pas y avoir deux objets de niveau supérieur.Map<String, String>
c'est: les bibliothèques de documentation API (swagger / springfox, etc.) ne seront probablement pas en mesure d'analyser votre schéma de demande / réponse à partir de votre code source.Vous pouvez mélanger l'argument post en utilisant la variable body et path pour des types de données plus simples:
la source
Pour passer plusieurs objets, paramètres, variables, etc. Vous pouvez le faire de manière dynamique en utilisant ObjectNode de la bibliothèque jackson comme paramètre. Vous pouvez le faire comme ceci:
J'espère que cette aide.
la source
@RequestParam
est le paramètreHTTP GET
ouPOST
envoyé par le client, le mappage de demande est un segment d'URL dont la variable:var1
&var2
sont des paramètres de requête.{params}
est un mappage de demande. vous pouvez appeler votre service comme:http:/host/form/user
ouhttp:/host/form/firm
où l'entreprise et l'utilisateur sont utilisés commePathvariable
.la source
La solution simple consiste à créer une classe de charge utile qui a les attributs str1 et str2:
Et après vous pouvez passer
et le corps de votre demande est:
la source
Au lieu d'utiliser json, vous pouvez faire des choses simples.
Maintenant, dans le contrôleur, vous devez mapper la demande ajax comme ci-dessous:
J'espère que cela vous aide.
la source
J'ai adapté la solution de Biju:
Quelle est la différence:
BR
la source
Le paramètre de requête existe pour GET et POST, pour Get, il sera ajouté en tant que chaîne de requête à l'URL mais pour POST, il se trouve dans le corps de la requête
la source
Je ne sais pas où vous ajoutez le json, mais si je le fais comme ça avec angular, cela fonctionne sans la requêteBody: angluar:
Java:
la source
Bien. Je suggère de créer un objet de valeur (Vo) qui contient les champs dont vous avez besoin. Le code est plus simple, on ne change pas le fonctionnement de Jackson et c'est encore plus facile à comprendre. Cordialement!
la source
Vous pouvez réaliser ce que vous voulez en utilisant
@RequestParam
. Pour cela, vous devez procéder comme suit:required
option sur false si vous souhaitez pouvoir envoyer une valeur nulle.Je sais, c'est un peu un hack mais ça marche! ;)
la source
vous pouvez également utiliser
@RequestBody Map<String, String> params
, puis utiliserparams.get("key")
pour obtenir la valeur du paramètrela source
Vous pouvez également utiliser une carte MultiValue pour contenir le requestBody. Voici l'exemple pour cela.
contrairement à l'annotation @RequestBody lorsque vous utilisez une carte pour contenir le corps de la requête, nous devons annoter avec @RequestParam
et envoyez l'utilisateur dans Json RequestBody
la source