Você está correto, o parâmetro anotado @RequestBody deve conter todo o corpo da solicitação e vincular-se a um objeto, portanto, você essencialmente terá que seguir suas opções.
Se você realmente deseja sua abordagem, há uma implementação personalizada que você pode fazer:
Diga que este é o seu json:
{
"str1": "test one",
"str2": "two test"
}
e você deseja vinculá-lo aos dois parâmetros aqui:
@RequestMapping(value = "/Test", method = RequestMethod.POST)
public boolean getTest(String str1, String str2)
Primeiro defina uma anotação personalizada, digamos @JsonArg
, com o caminho JSON como o caminho para as informações que você deseja:
public boolean getTest(@JsonArg("/str1") String str1, @JsonArg("/str2") String str2)
Agora escreva um HandlerMethodArgumentResolver personalizado que usa o JsonPath definido acima para resolver o argumento real:
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 "";
}
}
Agora, basta registrar isso com Spring MVC. Um pouco envolvido, mas isso deve funcionar de forma limpa.
@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface JsonArg { String value() default ""; }
Embora seja verdade que
@RequestBody
deve ser mapeado para um único objeto, esse objeto pode ser umMap
, então isso fornece a você um bom caminho para o que você está tentando alcançar (não há necessidade de escrever um objeto de apoio único):Você também pode vincular ao ObjectNode de Jackson se quiser uma árvore JSON completa:
fonte
Map
objeto para armazenar qualquer número de objetos dentro dele, mas o objeto de nível superior ainda deve ser apenas um, não pode haver dois objetos de nível superior.Map<String, String>
é: bibliotecas de documentação de API (swagger / springfox etc) provavelmente não serão capazes de analisar seu esquema de solicitação / resposta de seu código-fonte.Você pode misturar o argumento post usando body e path variable para tipos de dados mais simples:
fonte
Para passar vários objetos, parâmetros, variáveis e assim por diante. Você pode fazer isso dinamicamente usando ObjectNode da biblioteca jackson como seu parâmetro. Você pode fazer desta forma:
Espero esta ajuda.
fonte
@RequestParam
é o parâmetroHTTP GET
ouPOST
enviado pelo cliente, o mapeamento da solicitação é um segmento da URL cuja variável:var1
evar2
são parâmetros de solicitação.{params}
é um mapeamento de solicitação. você pode chamar seu serviço como:http:/host/form/user
ouhttp:/host/form/firm
onde firma e usuário são usados comoPathvariable
.fonte
A solução fácil é criar uma classe de carga útil que tenha str1 e str2 como atributos:
E depois você pode passar
e o corpo da sua solicitação é:
fonte
Em vez de usar json, você pode fazer coisas simples.
Agora, no controlador, você precisa mapear a solicitação ajax conforme abaixo:
Espero que isso ajude você.
fonte
Eu adaptei a solução do Biju:
Qual é a diferença:
BR
fonte
o parâmetro de solicitação existe para GET e POST, para Get será anexado como string de consulta ao URL, mas para POST está dentro do corpo da solicitação
fonte
Não tenho certeza de onde você adiciona o json, mas se eu fizer assim com o angular, ele funcionará sem o requestBody: angluar:
Java:
fonte
Boa. Eu sugiro criar um Value Object (Vo) que contenha os campos de que você precisa. O código é mais simples, não alteramos o funcionamento do Jackson e fica ainda mais fácil de entender. Saudações!
fonte
Você pode conseguir o que deseja usando
@RequestParam
. Para isso, você deve fazer o seguinte:required
opção como false se desejar enviar um valor nulo.Eu sei, é um pouco hack, mas funciona! ;)
fonte
você também pode
@RequestBody Map<String, String> params
usarparams.get("key")
para obter o valor do parâmetrofonte
Você também pode usar um Mapa MultiValue para conter o requestBody. Aqui está o exemplo para ele.
ao contrário da anotação @RequestBody ao usar um mapa para conter o corpo da solicitação, precisamos anotar com @RequestParam
e enviar ao usuário no Json RequestBody
fonte