67

具有以下代码:

@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!";
}

尽管 json 在正文中发送,但 String json 参数始终为空。

请注意,我不想要自动类型转换,我只想要普通的 json 结果。

例如,这有效:

@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);
}

可能我可以使用 ServletRequest 或 InputStream 作为参数来检索实际的正文,但我想知道是否有更简单的方法?

4

6 回答 6

97

到目前为止我发现的最好方法是:

@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

让我知道是否还有其他选择。

于 2013-07-26T22:17:11.907 回答
27

你可以使用

@RequestBody String pBody

于 2017-08-26T09:54:49.570 回答
20

只有 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!";
}
于 2018-02-27T14:15:22.787 回答
8

对我有用的最简单方法是

@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";
}
于 2016-09-06T09:42:00.730 回答
2

如果你有几十个 Method 需要将 HTTP body 获取为 JSON 并将其转换为自定义数据类型,这是在框架上实现支持的更好方法

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";
}

请注意,我们使用用户定义的注释@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());
    }
}
于 2020-04-24T08:56:47.000 回答
0

从 4.1 开始,您现在可以RequestEntity<String> requestEntity通过以下方式使用和访问正文requestEntity.getBody()

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/RequestEntity.html

于 2021-12-22T03:10:35.957 回答