Cannot forward to error page for request [/wechat/portal] as the response has already been commit

版权声明:本文为hoaven原创文章,未经博主允许不得转载。 https://blog.csdn.net/hehuanchun0311/article/details/80512765

1、问题描述

最近使用Spring Boot搭建 web 框架过程中遇到这样一个问题:该接口接收微信服务器的签名校验,但是请求的时候报了ERROR。

2018-05-30 13:56:14.265 ERROR - Cannot forward to error page for request 
[/wechat/portal/hdd] as the response has already been committed. As a 
result, the response may have the wrong status code. If your application 
is running on WebSphere Application Server you may be able to resolve this 
problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to 
false (o.s.boot.web.support.ErrorPageFilter:210) [http-nio-8080-exec-6]

2、解决方案

看日志提示是需要设置com.ibm.ws.webcontainer.invokeFlushAfterService为false。

    @Bean
    public ErrorPageFilter errorPageFilter() {
        return new ErrorPageFilter();
    }

    @Bean
    public FilterRegistrationBean disableSpringBootErrorFilter(ErrorPageFilter filter) {
         FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
         filterRegistrationBean.setFilter(filter);
         filterRegistrationBean.setEnabled(false);
         return filterRegistrationBean;
    }
  1. 改完后重新部署,的确不报ERROR了,但是接口报404。
  2. 此时各位可以检查自己的Url是否正确,我的情况是:
  3. 接口url没错,并且remote debug可以进去,也能正常return,但是查看localhost_access_log也确实404,可以说是千奇百怪了。

3、深入挖掘

贴上接口代码:

@GetMapping(produces = "text/plain;charset=utf-8")
    public String authGet(@RequestParam(name = "signature", required = false) String signature,
                          @RequestParam(name = "timestamp", required = false) String timestamp,
                          @RequestParam(name = "nonce", required = false) String nonce,
                          @RequestParam(name = "echostr", required = false) String echostr) {
        return authGet(signature, timestamp, nonce, echostr, null);
    }

    @ResponseBody
    @GetMapping(value = "/{channel}", produces = "text/plain;charset=utf-8")
    public String authGet(@RequestParam(name = "signature", required = false) String signature,
                          @RequestParam(name = "timestamp", required = false) String timestamp,
                          @RequestParam(name = "nonce", required = false) String nonce,
                          @RequestParam(name = "echostr", required = false) String echostr,
                          @PathVariable(name = "channel") String channel) {
        log.info("\n接收到来自微信服务器的认证消息 [{}, {}, {}, {},{}]", signature, timestamp, nonce, echostr, channel);

        if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
            throw new IllegalArgumentException("请求参数非法,请核实!");
        }

        WxMpService wxMpService = oldHxWeChatService;
        if (channel != null) {
            wxMpService = hxWeChatService;
        }
        if (wxMpService.checkSignature(timestamp, nonce, signature)) {
            return echostr;
        }

        return "非法请求";
    }

解决方案:使用response输出流或@ResponseBody

  1. response.getWriter().print(echostr);
  2. @responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据,需要注意的呢,在使用此注解之后不会再走试图处理器,而是直接将数据写入到流中,他的效果等同于通过response对象输出指定格式的数据。
  3. 因此可知之前直接使用return echostr spring会找不到对应的视图,但是视图找不到,spring又转到errorPage,但是项目中没有配置errorPage,从而404.

猜你喜欢

转载自blog.csdn.net/hehuanchun0311/article/details/80512765