解决使用@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 (); /*PageList blackDatas=(PageList )blackService.getPageData(params); data.put("total",blackDatas.getPaginator().getTotalCount()); data.put("rows",blackDatas);*/ //blackService.getPageData(params); /*Mapdata=newHashMap(); PageList blackDatas=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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。