解决使用@ResponseBody后返回500错误的问题
在springmvc+mybatis的项目中,利用mybatis分页插件mybatis-paginator进行分页查询,结果出现了500异常,后端又没有明显的报错。
原来的写法,返回Map对象,由springmvc里面的机制转为json对象,这样就会导致,在转json过程中的报错,都隐藏了,无法抛出,前端获取不到正确的数据,
最后就出现了500的异常。
@RequestMapping(value="/query") @ResponseBody publicMapdata(HttpServletRequestrequest,HttpServletResponseresponse,CreditloanInfoParamsparams){ Map data=newHashMap (); if(params==null){ params=newCreditloanInfoParams(); } PageList list=(PageList )creditloanInfoService.getCreditloanInfoListData(params); data.put("total",list.getPaginator().getTotalCount()); data.put("rows",list); returndata; }
改成使用fastJson主动转化为json格式的字符串,这样的好处是,转json过程中如果出现错误,会有很明确的提示。
@SuppressWarnings("unchecked")
@RequestMapping(value="/query")
@ResponseBody
publicStringdata(HttpServletRequestrequest,HttpServletResponseresponse,BlackParamsparams){
//Mapdata=newHashMap();
/*PageListblackDatas=(PageList)blackService.getPageData(params);
data.put("total",blackDatas.getPaginator().getTotalCount());
data.put("rows",blackDatas);*/
//blackService.getPageData(params);
/*Mapdata=newHashMap();
PageListblackDatas=blackService.getBlackListData(params);
data.put("total",blackDatas.getPaginator().getTotalCount());
data.put("rows",blackDatas);*/
returnJSON.toJSONString(blackService.getPageData(params));
}
最后发现是转json中出现了空指针异常。修复后,问题解决。
补充知识:springboot使用过滤器获取response内容保存接口访问日志
一、创建过滤器
1.在springboot的启动入口出添加注解@ServletComponentScan
@SpringBootApplication
@ServletComponentScan
publicclassApplication{
publicstaticvoidmain(String[]args){
SpringApplication.run(Applicatioin.class,args);
}
}
2.新建过滤器AccessLogFilter.java
@WebFilter(filterName="accessLog",urlPatterns="/api/*")
publicclassAccessLogFilterimplementsFilter{
@Autowired
AccessLogMapperaccessLogMapper;
publicvoiddestroy(){
}
publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{
longstartTime=System.currentTimeMillis();
ResponseWrapperwrapper=newResponseWrapper((HttpServletResponse)response);
HttpServletRequestreq=(HttpServletRequest)request;
chain.doFilter(request,wrapper);
longendTime=System.currentTimeMillis();
Gsongson=newGson();
//获取response返回的内容并重新写入response
Stringresult=wrapper.getResponseData(response.getCharacterEncoding());
response.getOutputStream().write(result.getBytes());
Stringuri=req.getRequestURI();
AccessLoglog=newAccessLog();
log.setMethod(req.getMethod());
log.setUrl(uri);
log.setParameters(gson.toJson(req.getParameterMap()));
log.setResponseCode(String.valueOf(wrapper.getStatus()));
log.setResult(result);
log.setCreateDatetime(newDate());
log.setTimeConsuming((int)(endTime-startTime));
accessLogMapper.insertSelective(log);
}
publicvoidinit(FilterConfigfConfig)throwsServletException{
}
}
这个过滤器使用了注解@WebFilter(filterName="accessLog",urlPatterns="/api/*")进行配置,指定了url进入规则,只有以/api/开头的url才能进入到此过滤器中。在doFilter方法中使用了自定义的ResponseWrapper对response进行封装。Controller接口走完之后获取到接口返回的数据并再次封装到response。
3.ResponseWrapper.java类
importjava.io.ByteArrayOutputStream;
importjava.io.CharArrayWriter;
importjava.io.IOException;
importjava.io.OutputStreamWriter;
importjava.io.PrintWriter;
importjava.io.UnsupportedEncodingException;
importjavax.servlet.ServletOutputStream;
importjavax.servlet.WriteListener;
importjavax.servlet.http.HttpServletResponse;
importjavax.servlet.http.HttpServletResponseWrapper;
publicclassResponseWrapperextendsHttpServletResponseWrapper{
privateByteArrayOutputStreambuffer=null;
privateServletOutputStreamout=null;
privatePrintWriterwriter=null;
publicResponseWrapper(HttpServletResponseresponse)throwsIOException{
super(response);
buffer=newByteArrayOutputStream();
out=newWapperedOutputStream(buffer);
writer=newPrintWriter(newOutputStreamWriter(buffer,"UTF-8"));
}
//重载父类获取outputstream的方法
@Override
publicServletOutputStreamgetOutputStream()throwsIOException{
returnout;
}
@Override
publicPrintWritergetWriter()throwsIOException{
returnwriter;
}
@Override
publicvoidflushBuffer()throwsIOException{
if(out!=null){
out.flush();
}
if(writer!=null){
writer.flush();
}
}
@Override
publicvoidreset(){
buffer.reset();
}
publicStringgetResponseData(Stringcharset)throwsIOException{
flushBuffer();//将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据
byte[]bytes=buffer.toByteArray();
try{
returnnewString(bytes,"UTF-8");
}catch(UnsupportedEncodingExceptione){
return"";
}
}
//内部类,对ServletOutputStream进行包装,指定输出流的输出端
privateclassWapperedOutputStreamextendsServletOutputStream{
privateByteArrayOutputStreambos=null;
publicWapperedOutputStream(ByteArrayOutputStreamstream)throwsIOException{
bos=stream;
}
//将指定字节写入输出流bos
@Override
publicvoidwrite(intb)throwsIOException{
bos.write(b);
}
@Override
publicbooleanisReady(){
//TODOAuto-generatedmethodstub
returnfalse;
}
@Override
publicvoidsetWriteListener(WriteListenerlistener){
//TODOAuto-generatedmethodstub
}
}
}
以上这篇解决使用@ResponseBody后返回500错误的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。