解决使用@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错误的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Springboot异常错误处理解决方案详解

    1.在有模板引擎的情况下: springboot会默认找 templates/error/错误状态码.html,所以我们要定制化错误页面就可以到templates/error下创建一个[对应错误状态码.html]html文件,当发生此状态码的错误springboot就会来到对应的页面. 同时如果我们想让400-499之间的错误都去同一个错误页面,那我们可以在templates/error下创建一个4xx.html.同理500-599的错误可以用5xx.html. 注意:springboot会优先

  • 解决layui table表单提示数据接口请求异常的问题

    问题一:直接拿别人的文件放在本地打开 如下图 原因:这是提示"交叉源请求仅支持协议方案:HTTP.数据.Chrome.Chrome扩展.HTTPS." 也就是你不能用本地文件打开,本地打开是file:///C:/Users/Administrator/Desktop/git/layui_table1.html 可以在本地服务器上展示没有问题 http://localhost/git/layui_table1.html 问题二:返回数据格式不符合要求(经常是这样的) 输出格式为 { &q

  • Spring boot自定义http反馈状态码详解

    前言 最近在开发一些http server类型程序,通过spring boot构建一些web程序,这些web程序之间通过http进行数据访问.共享,如下图, 假设现在client发起一次保存数据的请求到server,server可能会返回如下类似的数据 { "status":1, "message":"xxxxxx" } 然后client通过解析json获得status来判断当前的请求操作是否成功,开发过程中通过都是这么做的,但是这样在restf

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

    在springmvc+mybatis的项目中,利用mybatis分页插件mybatis-paginator进行分页查询,结果出现了500异常,后端又没有明显的报错. 原来的写法,返回Map对象,由springmvc里面的机制转为json对象,这样就会导致,在转json过程中的报错,都隐藏了,无法抛出,前端获取不到正确的数据, 最后就出现了500的异常. @RequestMapping(value = "/query") @ResponseBody public Map<Strin

  • 表单提交错误后返回内容消失问题的解决方法(PHP网站)

    表单提交错误后返回内容消失怎么办呐,今天就来分析解决一下这个问题. 状况概述: 做填写表单信息提交的时候会碰到一个问题就是当用户填写并提交表单后,程序判断不符合要求并返回,返回之后之前填写的表单信息会被清空了的情况.如果填写的信息量少还无所谓,如果填写的信息量比较多,这会直接打击到填写信息的人的良好心情.因此解决表单提交错误返回后填写的内容消失的问题是一个提高用户体验度的迫在眉睫的问题. 对于这种问题,综合总结了大概有下面几种情况: (1)页面使用了session_start函数,这个函数有个特

  • JSP中内建exception对象时出现500错误的解决方法

    本文实例讲述了JSP中内建exception对象时出现500错误的解决方法.分享给大家供大家参考,具体如下: 尝试使用JSP的内建exception对象,写了下面三个文件.思路很简单,文件index若提交字串为空,则get抛出异常,交由error.jsp处理.但实际却不能正常运行,会出现IE的500错误页面.环境为Tomcat 5.5,IE6.0. 在sun的论坛上有人贴出了原因,是IE的某个设置.Tomcat5.0以后的版本error page在处理时会返回error code 500.而IE

  • Win7 IIS7.5运行ASP时出现500错误的解决办法

    http 500内部服务器错误说明IIS服务器无法解析ASP代码,如果你联网还发现找不到服务器就是500错误了. 在iis7里面的iis设置要开启启用父路径这个选项,之后就可以了,当然为了调试程序可以打开"ASP设置选项-调试属性"里面的一些调试功能,方便程序的调试. Win7 IIS7.5运行ASP时出现500错误的解决办法 请确保在你的电脑上IIS配置完成了,静态页面能打开了,但是打开ASP就会出现500错误.再进行下面配置.具体如下: 一.进入"C:\Windows\S

  • IIS7.5中调试.Net 4.0网站出现无厘头、500错误的解决方法

    刚刚 部署了ii7的dll的有x86写的,就会出现以下这样的问题 iis 7 x86,Could not load file or assembly 'Name' or one of its dependencies. An attempt was made to load a program with an incorrect format. 解决这样的,只要设置一下iis兼容x86程序就可以了,具体步骤: 1.开始-> 运行 2. 3. 高级设置, Enable 32 - Bit Appli

  • 解决RestTemplate 请求接收自定义400+ 或500+错误

    目录 RestTemplate 请求接收自定义400+ 或500+错误 场景 原因 解决办法 自定义RestTemplate的ResponseErrorHandler Spring框架中的RestTemplate处理ClientHttpResponse的方式 并不想让它抛异常 无法使用IOC注入的场景下 RestTemplate 请求接收自定义400+ 或500+错误 场景 当服务端自定义400错误返回体时,使用restTemplate 请求接收不到消息体.而我正想根据不同的错误信息做不同的操作

  • nginx如何指向本地路径及500错误解决方法

    正文 一个vite+vue3项目,想要部署到服务器上.项目build后的文件都在dist目录下,将这个目录拷贝到服务器上,然后在nginx里进行配置,如下: server { listen 3571; server_name localhost; location / { root /root/xxxx/dist/; try_files $uri $uri/ /index.html; } } 这样就可以通过服务器的公网ip+端口3571来访问这个vue项目了,如果想通过域名访问,则可以这样配置:

  • PHPExcel在linux环境下导出报500错误的解决方法

    原先我导出为 XLSX 格式,用的是 $objWriter = IOFactory::createWriter($objPHPExcel, 'Excel2007'); 报错,纠结就纠结在,在开发环境和测试环境都没问题,放在生产环境直接 500 错误. 后来我改成导出 XLS 格式, $objWriter = IOFactory::createWriter($objPHPExcel, 'Excel5'); 问题解决了,具体为什么待有空了研究下!!! 以上这篇PHPExcel在linux环境下导出报

  • IIS7使用.NET Framework v4.0运行库报500错误的解决办法

    故障说明:1)Windows Server 2008 R2环境下安装的IIS7.52)安装.Net4.53)运行网站,报500错误:检查了webconfig等代码,没有问题 解决办法:重新注册.Net4.5,过程如下:一.开始,查找框中输入cmd字眼,然后出现cmd.exe应用程序二.cmd.exe上右键,选择用管理员身份来运行. 三.往命令行窗口中粘贴以下命令,回车,完成注册. 复制代码 代码如下: "%WINDIR%\Microsoft.NET\Framework\v4.0.30319\as

  • Kloxo面板无法登录出现500错误的解决方法

    如果您的VPS服务器安装的是Kloxo管理系统,打开网站突然出现各种代码错误,同时Kloxo面板无法登录提示500错误,那么这种情况一般是日志满了造成的,清空日志的步骤如下: 1.putty远程进入系统,用 df -l 命令查看空间容量情况.其中Used这栏就是使用情况,如果出现100%,说明容量已经满了. 2.执行以下命令,删除日志. cd /home/admin/ cd __processed_stats rm -f * 3.再重启Kloxo,让Kloxo恢复正常.重启命令为: servic

随机推荐