Ist es notwendig, ein Gegenstandsobjekt einzuwickeln? Ich möchte das machen:
@RequestMapping(value = "/Test", method = RequestMethod.POST)
@ResponseBody
public boolean getTest(@RequestBody String str1, @RequestBody String str2) {}
Und benutze eine JSON wie folgt:
{
"str1": "test one",
"str2": "two test"
}
Stattdessen muss ich verwenden:
@RequestMapping(value = "/Test", method = RequestMethod.POST)
@ResponseBody
public boolean getTest(@RequestBody Holder holder) {}
Und dann benutze diesen JSON:
{
"holder": {
"str1": "test one",
"str2": "two test"
}
}
Ist das korrekt? Meine andere Option wäre, RequestMethod
in GET
zu ändern und @RequestParam
in der Abfragezeichenfolge oder @PathVariable
mit RequestMethod
zu verwenden.
Wenn Sie richtig sind, wird erwartet, dass der annotierte @RequestBody-Parameter den gesamten Text der Anforderung enthält und an ein Objekt bindet, sodass Sie im Wesentlichen Ihre Optionen wählen müssen.
Wenn Sie Ihren Ansatz unbedingt wollen, gibt es eine benutzerdefinierte Implementierung, die Sie jedoch ausführen können:
Sag das ist dein 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 zuerst eine benutzerdefinierte Anmerkung, beispielsweise @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 das oben definierte JsonPath verwendet, um das tatsächliche 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 "";
}
}
Jetzt registrieren Sie dies einfach bei Spring MVC. Ein bisschen beteiligt, aber das sollte sauber funktionieren.
Es ist zwar wahr, dass @RequestBody
einem einzelnen Objekt zugeordnet werden muss, dieses Objekt kann jedoch eine Map
sein. Dadurch erhalten Sie einen guten Weg zu dem, was Sie erreichen möchten (es ist nicht erforderlich, ein einzelnes Objekt aus einem Sicherungsobjekt zu schreiben):
@RequestMapping(value = "/Test", method = RequestMethod.POST)
@ResponseBody
public boolean getTest(@RequestBody Map<String, String> json) {
//json.get("str1") == "test one"
}
Sie können auch an Jacksons ObjectNode binden, wenn Sie einen vollständigen JSON-Baum wünschen:
public boolean getTest(@RequestBody ObjectNode json) {
//json.get("str1").asText() == "test one"
Sie können das Post-Argument mit einfachen Text- und Pfadvariablen für einfachere Datentypen mischen:
@RequestMapping(value = "new-trade/portfolio/{portfolioId}", method = RequestMethod.POST)
public ResponseEntity<List<String>> newTrade(@RequestBody Trade trade, @PathVariable long portfolioId) {
...
}
@RequestParam
ist der vom Client gesendete Parameter HTTP GET
oder POST
, Request Mapping ist ein Segment der URL, dessen Variable:
http:/Host/form_edit?param1=val1¶m2=val2
var1
& var2
sind Anforderungsparameter.
http:/Host/form/{params}
{params}
ist eine Anforderungszuordnung. Sie können Ihren Dienst wie folgt anrufen: http:/Host/form/user
oder http:/Host/form/firm
Dabei werden Firma und Benutzer als Pathvariable
verwendet.
Zum Übergeben mehrerer Objekte, Parameter, Variablen usw. Sie können dies dynamisch tun, indem Sie ObjectNode aus der Jackson-Bibliothek als Parameter verwenden. Du kannst es so machen:
@RequestMapping(value = "/Test", method = RequestMethod.POST)
@ResponseBody
public boolean getTest(@RequestBody ObjectNode objectNode) {
// And then you can call parameters from objectNode
String strOne = objectNode.get("str1").asText();
String strTwo = objectNode.get("str2").asText();
// When you using ObjectNode, you can pas other data such as:
// instance object, array list, nested object, etc.
}
Ich hoffe diese Hilfe.
Sie können erreichen, was Sie wollen, indem Sie @RequestParam
verwenden. Dafür sollten Sie Folgendes tun:
required
auf false, wenn Sie einen Nullwert senden möchten.Ich weiß, es ist ein bisschen ein Hack, aber es funktioniert! ;)
Ich weiß nicht, wo man den Json hinzufügt, aber wenn ich es so mit eckig mache, funktioniert es auch ohne 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);
}
Gut . Ich empfehle, ein Wertobjekt (Vo) zu erstellen, das die benötigten Felder enthält. Der Code ist einfacher, wir ändern die Funktion von Jackson nicht und es ist sogar noch einfacher zu verstehen.
sie können auch @RequestBody Map<String, String> params
verwenden und dann params.get("key")
verwenden, um den Wert des Parameters abzurufen
anforderungsparameter sind sowohl für GET als auch für POST vorhanden. Für Get wird es als Abfragezeichenfolge an die URL angehängt, für POST befindet es sich jedoch innerhalb des Anforderungstextes
Ich habe die Lösung von Biju angepasst:
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;
}
}
Was ist der Unterschied:
BR
Anstatt Json zu verwenden, können Sie einfache Dinge tun.
$.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.>
});
Jetzt müssen Sie im Controller die Ajax-Anforderung wie folgt zuordnen:
@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";
}
Hoffe das hilft dir.