解决使用@ResponseBody后返回500错误的问题

 更新时间:2020年09月15日 08:48:50   作者:斗者_2013  
这篇文章主要介绍了解决使用@ResponseBody后返回500错误的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

在springmvc+mybatis的项目中,利用mybatis分页插件mybatis-paginator进行分页查询,结果出现了500异常,后端又没有明显的报错。

原来的写法,返回Map对象,由springmvc里面的机制转为json对象,这样就会导致,在转json过程中的报错,都隐藏了,无法抛出,前端获取不到正确的数据,

最后就出现了500的异常。

 @RequestMapping(value = "/query")
 @ResponseBody
 public Map<String, Object> data(HttpServletRequest request, HttpServletResponse response, CreditloanInfoParams params) {
 Map<String, Object> data = new HashMap<String, Object>();
 if(params==null){
 params=new CreditloanInfoParams();
 }
 PageList<CreditloanInfo> list = (PageList<CreditloanInfo>) creditloanInfoService.getCreditloanInfoListData(params);
 data.put("total", list.getPaginator().getTotalCount());
 data.put("rows", list);
 return data;
 }

改成使用fastJson主动转化为json格式的字符串,这样的好处是,转json过程中如果出现错误,会有很明确的提示。

 @SuppressWarnings("unchecked")
 @RequestMapping(value = "/query")
 @ResponseBody
 public String data(HttpServletRequest request, HttpServletResponse response, BlackParams params) {
 //Map<String, Object> data = new HashMap<String, Object>();
 /*PageList<Blacklist> blackDatas = (PageList<Blacklist>) blackService.getPageData(params);
 data.put("total", blackDatas.getPaginator().getTotalCount());
 data.put("rows", blackDatas);*/
 //blackService.getPageData(params);
/* Map data = new HashMap();
 PageList<Blacklist> blackDatas = blackService.getBlackListData(params);
 data.put("total", blackDatas.getPaginator().getTotalCount());
 data.put("rows", blackDatas);*/
 return JSON.toJSONString(blackService.getPageData(params));
 }

最后发现是转json中出现了空指针异常。修复后,问题解决。

补充知识:springboot 使用过滤器获取response内容保存接口访问日志

一、创建过滤器

1. 在spring boot的启动入口出添加注解 @ServletComponentScan

@SpringBootApplication 
@ServletComponentScan
public class Application {
 public static void main(String[] args) {
  SpringApplication.run(Applicatioin.class, args);
 }
}

2.新建过滤器AccessLogFilter.java

@WebFilter(filterName = "accessLog", urlPatterns = "/api/*")
public class AccessLogFilter implements Filter {
 
 @Autowired
 AccessLogMapper accessLogMapper; 
 public void destroy() { 
 } 
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
 long startTime = System.currentTimeMillis();
 ResponseWrapper wrapper = new ResponseWrapper((HttpServletResponse) response);
 HttpServletRequest req = (HttpServletRequest) request;
 
 chain.doFilter(request, wrapper);
 long endTime = System.currentTimeMillis();
 Gson gson = new Gson();
 // 获取response返回的内容并重新写入response
 
 String result = wrapper.getResponseData(response.getCharacterEncoding());
 response.getOutputStream().write(result.getBytes());   
 String uri = req.getRequestURI();
 AccessLog log = new AccessLog(); 
 log.setMethod(req.getMethod());
 log.setUrl(uri);
 log.setParameters(gson.toJson(req.getParameterMap()));
 log.setResponseCode(String.valueOf(wrapper.getStatus()));
 log.setResult(result);
 log.setCreateDatetime(new Date());
 log.setTimeConsuming((int)(endTime - startTime));
 accessLogMapper.insertSelective(log);
 } 
 public void init(FilterConfig fConfig) throws ServletException { 
 } 
}

这个过滤器使用了注解@WebFilter(filterName = "accessLog", urlPatterns = "/api/*") 进行配置,指定了url进入规则,只有以/api/开头的url才能进入到此过滤器中。在doFilter方法中使用了自定义的ResponseWrapper对response进行封装。Controller接口走完之后获取到接口返回的数据并再次封装到response。

3. ResponseWrapper.java 类

import java.io.ByteArrayOutputStream;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
 
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper; 
public class ResponseWrapper extends HttpServletResponseWrapper { 
 private ByteArrayOutputStream buffer = null; 
 private ServletOutputStream out = null; 
 private PrintWriter writer = null; 
 
 public ResponseWrapper(HttpServletResponse response) throws IOException{
 super(response);
  
  buffer = new ByteArrayOutputStream();
  out = new WapperedOutputStream(buffer);
  writer = new PrintWriter(new OutputStreamWriter(buffer, "UTF-8"));
 }
 
 //重载父类获取outputstream的方法
 @Override
 public ServletOutputStream getOutputStream() throws IOException {
  return out;
 }
 
 @Override
 public PrintWriter getWriter() throws IOException {
  return writer;
 }
 
 @Override
 public void flushBuffer() throws IOException {
  if (out != null) {
   out.flush();
  }
  if (writer != null) {
   writer.flush();
  }
 }
 
 @Override
 public void reset() {
  buffer.reset();
 }
 
 public String getResponseData(String charset) throws IOException {
  flushBuffer();//将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据
  byte[] bytes = buffer.toByteArray(); 
  try {
   return new String(bytes, "UTF-8");
  } catch (UnsupportedEncodingException e) {
   return "";
  } 
 } 
 
 //内部类,对ServletOutputStream进行包装,指定输出流的输出端
 
 private class WapperedOutputStream extends ServletOutputStream { 
  private ByteArrayOutputStream bos = null; 
  public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException {
   bos = stream;
  }
 
  //将指定字节写入输出流bos
  @Override
  public void write(int b) throws IOException {
   bos.write(b);
  }
 
 @Override
 public boolean isReady() {
 // TODO Auto-generated method stub
 return false;
 }
 
 @Override
 public void setWriteListener(WriteListener listener) {
 // TODO Auto-generated method stub
 
 }
 } 
}

以上这篇解决使用@ResponseBody后返回500错误的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java实现分解任意输入数的质因数算法示例

    Java实现分解任意输入数的质因数算法示例

    这篇文章主要介绍了Java实现分解任意输入数的质因数算法,涉及java数学运算相关操作技巧,需要的朋友可以参考下
    2017-10-10
  • IDEA未配置SQL方言:无法使用SQL提示解决方法

    IDEA未配置SQL方言:无法使用SQL提示解决方法

    在使用IDEA进行SQL开发时,如果未配置SQL方言可能会导致一些问题,如无法正确识别数据库中的关键字、数据类型等,这篇文章主要给大家介绍了关于IDEA未配置SQL方言,无法使用SQL提示解决方法的相关资料,需要的朋友可以参考下
    2024-07-07
  • MyBatis-Plus 通用IService使用详解

    MyBatis-Plus 通用IService使用详解

    这篇文章主要介绍了MyBatis-Plus 通用IService使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • springboot整合gateway实现网关功能的示例代码

    springboot整合gateway实现网关功能的示例代码

    本文主要介绍了springboot整合gateway实现网关功能的示例代码,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • Java中Thread类的使用和它的属性

    Java中Thread类的使用和它的属性

    在java中可以进行多线程编程,在java标准库中提供了一个Thread类,来表示线程操作,本文主要介绍了Java中Thread类的使用和它的属性,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • Spring容器添加组件方式实现

    Spring容器添加组件方式实现

    这篇文章主要介绍了Spring容器添加组件方式实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • RabbitMQ交换机使用场景和消息可靠性总结分析

    RabbitMQ交换机使用场景和消息可靠性总结分析

    这篇文章主要为大家介绍了RabbitMQ交换机使用场景和消息可靠性总结分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • 在Mac OS上安装Tomcat服务器的教程

    在Mac OS上安装Tomcat服务器的教程

    这篇文章主要介绍了在Mac OS上安装Tomcat服务器的教程,方便进行工作环境下的Java web开发,需要的朋友可以参考下
    2015-11-11
  • Java检测线程中断状态的方法示例

    Java检测线程中断状态的方法示例

    这篇文章主要介绍了Java检测线程中断状态的方法,结合实例形式分析了java针对线程中断状态检测的相关实现技巧,需要的朋友可以参考下
    2019-10-10
  • Java--SSH,SSM和Spring Boot框架区别及优缺点说明

    Java--SSH,SSM和Spring Boot框架区别及优缺点说明

    这篇文章主要介绍了Java--SSH,SSM和Spring Boot框架区别及优缺点说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12

最新评论