Masz rację, parametr @RequestBody z adnotacjami powinien przechowywać całą treść żądania i wiązać się z jednym obiektem, więc zasadniczo będziesz musiał przejść z opcjami.
Jeśli absolutnie chcesz swoje podejście, istnieje niestandardowa implementacja, którą możesz zrobić:
Powiedz, że to Twój plik json:
{
"str1": "test one",
"str2": "two test"
}
i chcesz powiązać go z dwoma parametrami tutaj:
@RequestMapping(value = "/Test", method = RequestMethod.POST)
public boolean getTest(String str1, String str2)
Najpierw zdefiniuj niestandardową adnotację, powiedzmy @JsonArg
, ze ścieżką JSON, taką jak ścieżka do żądanych informacji:
public boolean getTest(@JsonArg("/str1") String str1, @JsonArg("/str2") String str2)
Teraz napisz Custom HandlerMethodArgumentResolver, który używa zdefiniowanej powyżej JsonPath do rozwiązania rzeczywistego argumentu:
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 "";
}
}
Teraz po prostu zarejestruj to w Spring MVC. Trochę zawiłe, ale powinno to działać czysto.
@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface JsonArg { String value() default ""; }
Chociaż prawdą jest, że
@RequestBody
musi być mapowany na pojedynczy obiekt, ten obiekt może być aMap
, więc daje to dobry sposób na to, co próbujesz osiągnąć (nie ma potrzeby zapisywania pojedynczego obiektu zapasowego):Możesz także powiązać się z ObjectNode Jacksona, jeśli chcesz mieć pełne drzewo JSON:
źródło
Map
obiektu do przechowywania dowolnej liczby obiektów w nim, ale obiekt najwyższego poziomu nadal musi być tylko jeden, nie może być dwóch obiektów najwyższego poziomu.Map<String, String>
jest to, że biblioteki dokumentacji API (swagger / springfox itp.) Prawdopodobnie nie będą w stanie przeanalizować schematu żądania / odpowiedzi z kodu źródłowego.Możesz pomieszać argument post, używając zmiennej body i path dla prostszych typów danych:
źródło
Do przekazywania wielu obiektów, parametrów, zmiennych i tak dalej. Możesz to zrobić dynamicznie, używając ObjectNode z biblioteki jackson jako swojego parametru. Możesz to zrobić w ten sposób:
Mam nadzieję, że to pomoże.
źródło
@RequestParam
to parametrHTTP GET
lubPOST
wysyłany przez klienta, mapowanie żądań to segment adresu URL, którego zmienna:var1
ivar2
są parametrami żądania.{params}
jest mapowaniem żądań. możesz zadzwonić do swojej usługi na przykład:http:/host/form/user
lubhttp:/host/form/firm
gdzie firma i użytkownik są używane jakoPathvariable
.źródło
Prostym rozwiązaniem jest utworzenie klasy ładunku, która ma atrybuty str1 i str2:
A po przejściu
a treść Twojej prośby to:
źródło
Zamiast używać json, możesz zrobić prostą rzecz.
Teraz w kontrolerze musisz zmapować żądanie Ajax, jak poniżej:
Mam nadzieję, że to ci pomoże.
źródło
Dostosowałem rozwiązanie Biju:
Jaka jest różnica:
BR
źródło
parametr żądania istnieje zarówno dla GET, jak i POST, w przypadku polecenia Get zostanie dołączony jako ciąg zapytania do adresu URL, ale w przypadku POST znajduje się w treści żądania
źródło
Nie jestem pewien, gdzie dodasz json, ale jeśli zrobię to w ten sposób z angularem, działa bez requestBody: angluar:
Jawa:
źródło
Dobry. Proponuję utworzyć obiekt wartości (Vo) zawierający potrzebne pola. Kod jest prostszy, nie zmieniamy działania Jacksona i jest jeszcze łatwiejszy do zrozumienia. Pozdrowienia!
źródło
Możesz osiągnąć to, co chcesz, używając
@RequestParam
. W tym celu wykonaj następujące czynności:required
opcję na false, jeśli chcesz mieć możliwość wysyłania wartości null.Wiem, to trochę hack, ale działa! ;)
źródło
możesz także
@RequestBody Map<String, String> params
użyć użytkownika , a następnie użyj,params.get("key")
aby uzyskać wartość parametruźródło
Możesz również użyć mapy MultiValue do przechowywania requestBody. Oto przykład na to.
w przeciwieństwie do adnotacji @RequestBody, gdy używamy mapy do przechowywania treści żądania, musimy dodać adnotację za pomocą @RequestParam
i wyślij użytkownika w Json RequestBody
źródło