【问题标题】:Read HttpServletRequest object from Spring Boot controller method从 Spring Boot 控制器方法中读取 HttpServletRequest 对象
【发布时间】:2020-01-13 20:12:04
【问题描述】:

下面是我的控制器方法定义

@Autowired
private HttpServletRequest request;

@PostMapping(path = "/abc")
public String createAbc(@RequestBody HttpServletRequest request)
        throws IOException {

    logger.info("Request body: "+request.getInputStream());

    return "abc";

}

我要做的就是打印内容以请求正文。 但是当我发出 POST 请求时,我看到以下错误:

类型定义错误:[简单类型,类 javax.servlet.http.HttpServletRequest];嵌套异常是 com.fasterxml.jackson.databind.exc.InvalidDefinitionException:不能 构造javax.servlet.http.HttpServletRequest 的实例(没有 创建者,如默认构造,存在):抽象类型要么需要 映射到具体类型,具有自定义反序列化器,或包含 [Source: (PushbackInputStream); 处的其他类型信息\n线: 1、列:2]",

我使用的是 Spring boot 2.x 版本。知道我的代码有什么问题吗?

【问题讨论】:

  • 您已经有autowired 的请求。你从哪里得到@RequestBody HttpServletRequest request

标签: java spring rest spring-boot spring-mvc


【解决方案1】:

首先,删除@Autowired 字段。错了,反正你也没用。

现在你有两个选择:

  1. 让Spring为你处理请求体,使用@RequestBody注解:

    @PostMapping(path = "/abc")
    public String createAbc(@RequestBody String requestBody) throws IOException {
        logger.info("Request body: " + requestBody);
        return "abc";
    }
    
  2. 自己处理,即不要使用@RequestBody注解:

    @PostMapping(path = "/abc")
    public String createAbc(HttpServletRequest request) throws IOException {
        StringBuilder builder = new StringBuilder();
        try (BufferedReader in = request.getReader()) {
            char[] buf = new char[4096];
            for (int len; (len = in.read(buf)) > 0; )
                builder.append(buf, 0, len);
        }
        String requestBody = builder.toString();
        logger.info("Request body: " + requestBody);
        return "abc";
    }
    

不知道您为什么要使用选项 2,但如果您愿意,可以。

【讨论】:

  • 删除@Autowired 字段。这是错误的 - 你能解释为什么它是错误的 吗?见于stackoverflow.com/questions/3320674/…
  • @ScaryWombat 好吧,确实,对于 singleton bean 来说是错误的。您提供的那个链接没有错,因为它明确表示它是一个 request-scoped bean。由于this question没有指定,bean的默认类型是singleton,所以会出错。此外,为什么要创建一个 request-scoped bean,而单例 bean 就足够了?无论如何,将HttpServletRequest 作为自动装配字段 作为参数肯定是错误的。
  • bean 的默认类型是单例,所以会出错 - 谢谢
  • @ScaryWombat 是的,您必须添加另一个注释来更改范围,例如@Scope(WebApplicationContext.SCOPE_REQUEST)。如果没有 @Scope 注释,则 bean 是单例的。
  • @Andreas 您希望选择选项 2 的原因之一是您没有收到纯文本形式的帖子,而是收到客户端发送的 gzip 之类的内容。您当然不会使用字符串生成器来解压缩数据,而是使用 GZIPInputStream 之类的东西并将其转储为普通字符串,但这就是您需要访问 HttpServletRequest 的原因之一。所以,谢谢朋友的回答,非常有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-10
  • 2019-05-05
  • 2020-10-19
  • 1970-01-01
  • 1970-01-01
  • 2018-11-17
相关资源
最近更新 更多