Sie haben Recht, es wird erwartet, dass der mit @RequestBody annotierte Parameter den gesamten Hauptteil der Anforderung enthält und an ein Objekt bindet, sodass Sie im Wesentlichen mit Ihren Optionen arbeiten müssen.
Wenn Sie Ihren Ansatz unbedingt wollen, gibt es eine benutzerdefinierte Implementierung, die Sie jedoch ausführen können:
Sagen Sie, das ist Ihr json:
{
"str1": "test one",
"str2": "two test"
}
und Sie möchten es hier an die beiden Parameter binden:
@RequestMapping(value = "/Test", method = RequestMethod.POST)
public boolean getTest(String str1, String str2)
Definieren Sie zunächst eine benutzerdefinierte Anmerkung, z. B. @JsonArg
mit dem JSON-Pfad wie dem Pfad zu den gewünschten Informationen:
public boolean getTest(@JsonArg("/str1") String str1, @JsonArg("/str2") String str2)
Schreiben Sie nun einen benutzerdefinierten HandlerMethodArgumentResolver, der den oben definierten JsonPath verwendet , um das eigentliche Argument aufzulösen:
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 "";
}
}
Registrieren Sie dies jetzt einfach bei Spring MVC. Ein bisschen kompliziert, aber das sollte sauber funktionieren.
@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface JsonArg { String value() default ""; }
Es ist zwar richtig, dass
@RequestBody
ein Objekt einem einzelnen Objekt zugeordnet werden muss, aber dieses Objekt kann ein Objekt sein. AufMap
diese Weise erhalten Sie einen guten Weg zu dem, was Sie erreichen möchten (Sie müssen kein einmaliges Hintergrundobjekt schreiben):Sie können auch an Jacksons ObjectNode binden, wenn Sie einen vollständigen JSON-Baum wünschen:
quelle
Map
Objekt verwenden, um eine beliebige Anzahl von Objekten darin zu speichern, aber das Objekt der obersten Ebene muss immer noch nur eines sein, es können nicht zwei Objekte der obersten Ebene vorhanden sein.Map<String, String>
ist: API-Dokumentationsbibliotheken (swagger / springfox usw.) können Ihr Anforderungs- / Antwortschema wahrscheinlich nicht aus Ihrem Quellcode analysieren.Sie können das Post-Argument verwechseln, indem Sie für einfachere Datentypen body- und path-Variablen verwenden:
quelle
Zum Übergeben mehrerer Objekte, Parameter, Variablen usw. Sie können dies dynamisch tun, indem Sie ObjectNode aus der Jackson-Bibliothek als Parameter verwenden. Sie können es so machen:
Ich hoffe diese Hilfe.
quelle
@RequestParam
ist der vom Client gesendete ParameterHTTP GET
oder. DiePOST
Anforderungszuordnung ist ein Segment der URL, dessen Variable:var1
&var2
sind Anforderungsparameter.{params}
ist eine Anforderungszuordnung. Sie können Ihren Dienst wie folgt anrufen:http:/host/form/user
oderhttp:/host/form/firm
wo Firma & Benutzer als verwendet werdenPathvariable
.quelle
Die einfache Lösung besteht darin, eine Nutzlastklasse zu erstellen, deren Attribute str1 und str2 sind:
Und nachdem Sie passieren können
und der Hauptteil Ihrer Anfrage ist:
quelle
Anstatt json zu verwenden, können Sie auch einfache Dinge tun.
Jetzt müssen Sie im Controller die Ajax-Anforderung wie folgt zuordnen:
Hoffe das hilft dir.
quelle
Ich habe die Lösung von Biju angepasst:
Was ist der Unterschied:
BR
quelle
Der Anforderungsparameter ist sowohl für GET als auch für POST vorhanden. Für Get wird er als Abfragezeichenfolge an die URL angehängt, für POST befindet er sich jedoch im Anforderungshauptteil
quelle
Ich bin mir nicht sicher, wo du den JSON hinzufügst, aber wenn ich es so mit Winkel mache, funktioniert es ohne die Anfrage. Body: angluar:
Java:
quelle
Gut. Ich schlage vor, ein Wertobjekt (Vo) zu erstellen, das die benötigten Felder enthält. Der Code ist einfacher, wir ändern die Funktionsweise von Jackson nicht und es ist noch einfacher zu verstehen. Grüße!
quelle
Sie können erreichen, was Sie wollen, indem Sie verwenden
@RequestParam
. Dazu sollten Sie Folgendes tun:required
Option auf false, wenn Sie einen Nullwert senden möchten.Ich weiß, es ist ein bisschen ein Hack, aber es funktioniert! ;)
quelle
Sie können auch Benutzer verwenden
@RequestBody Map<String, String> params
und dann verwendenparams.get("key")
, um den Wert des Parameters abzurufenquelle
Sie können auch eine MultiValue-Map verwenden, um den requestBody zu speichern. Hier ist das Beispiel dafür.
Im Gegensatz zur Annotation @RequestBody, wenn eine Map zum Speichern des Anforderungshauptteils verwendet wird, müssen Annotationen mit @RequestParam erfolgen
und senden Sie den Benutzer im Json RequestBody
quelle