如何在 Spring rest 控制器中访问纯 json 主体?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17866996/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to access plain json body in Spring rest controller?
提问by Marcel Overdijk
Having the following code:
具有以下代码:
@RequestMapping(value = "/greeting", method = POST, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE)
@ResponseBody
public String greetingJson(@RequestBody String json) {
System.out.println("json = " + json); // TODO json is null... how to retrieve plain json body?
return "Hello World!";
}
The String json argument is always null despite json being sent in the body.
尽管在正文中发送了 json,但 String json 参数始终为 null。
Notethat I don't want automatic type conversion, I just want the plain json result.
请注意,我不想要自动类型转换,我只想要普通的 json 结果。
This for example works:
例如,这有效:
@RequestMapping(value = "/greeting", method = POST, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE)
@ResponseBody
public String greetingJson(@RequestBody User user) {
return String.format("Hello %s!", user);
}
Probably I can use the use the ServletRequest or InputStream as argument to retrieve the actual body, but I wonder if there is an easier way?
也许我可以使用使用 ServletRequest 或 InputStream 作为参数来检索实际正文,但我想知道是否有更简单的方法?
回答by Marcel Overdijk
Best way I found until now is:
到目前为止,我发现的最佳方法是:
@RequestMapping(value = "/greeting", method = POST, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE)
@ResponseBody
public String greetingJson(HttpEntity<String> httpEntity) {
String json = httpEntity.getBody();
// json contains the plain json string
Let me know if there are other alternatives.
让我知道是否还有其他选择。
回答by aGO
You can just use
你可以使用
@RequestBody String pBody
@RequestBody String pBody
回答by Jarno Argillander
Only HttpServletRequest worked for me. HttpEntity gave null string.
只有 HttpServletRequest 对我有用。HttpEntity 给出了空字符串。
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.IOUtils;
@RequestMapping(value = "/greeting", method = POST, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE)
@ResponseBody
public String greetingJson(HttpServletRequest request) throws IOException {
final String json = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
System.out.println("json = " + json);
return "Hello World!";
}
回答by david cassidy
simplest way that works for me is
对我有用的最简单的方法是
@RequestMapping(value = "/greeting", method = POST, consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String greetingJson(String raw) {
System.out.println("json = " + raw);
return "OK";
}
回答by Joseph
If you want spring to convert a json http body to argument type object automatically, this is a solution.
如果您希望 spring 自动将 json http body 转换为参数类型对象,这是一个解决方案。
public static class Data {
private String foo;
private String bar;
}
//convert http body to Data object.
//you can also use String parameter type to get the raw json text.
@RequestMapping(value = "/greeting")
@ResponseBody
public String greetingJson(@JsonBody Data data) {
System.out.println(data);
return "OK";
}
notice that we using user defined annotation @JsonBody.
请注意,我们使用用户定义的注释@JsonBody。
// define custom annotation
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface JsonBody {
String encoding() default "utf-8";
}
//annotation processor for JsonBody
@Slf4j
public class JsonBodyArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterAnnotation(JsonBody.class) != null;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
JsonBody annotation = parameter.getParameterAnnotation(JsonBody.class);
assert annotation != null;
ServletRequest servletRequest = webRequest.getNativeRequest(ServletRequest.class);
if (servletRequest == null) {
throw new Exception("can not get ServletRequest from NativeWebRequest");
}
String copy = StreamUtils.copyToString(servletRequest.getInputStream(), Charset.forName(annotation.encoding()));
return new Gson().fromJson(copy, parameter.getGenericParameterType());
}
}
// register the annotation processor
@Component
public class WebConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new JsonBodyArgumentResolver());
}
}

