解決使用@ResponseBody后返回500錯誤的問題
在springmvc+mybatis的項目中,利用mybatis分頁插件mybatis-paginator進(jìn)行分頁查詢,結(jié)果出現(xiàn)了500異常,后端又沒有明顯的報錯。
原來的寫法,返回Map對象,由springmvc里面的機(jī)制轉(zhuǎn)為json對象,這樣就會導(dǎo)致,在轉(zhuǎn)json過程中的報錯,都隱藏了,無法拋出,前端獲取不到正確的數(shù)據(jù),
最后就出現(xiàn)了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主動轉(zhuǎn)化為json格式的字符串,這樣的好處是,轉(zhuǎn)json過程中如果出現(xiàn)錯誤,會有很明確的提示。
@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));
}
最后發(fā)現(xiàn)是轉(zhuǎn)json中出現(xiàn)了空指針異常。修復(fù)后,問題解決。
補(bǔ)充知識:springboot 使用過濾器獲取response內(nèi)容保存接口訪問日志
一、創(chuàng)建過濾器
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返回的內(nèi)容并重新寫入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/*") 進(jìn)行配置,指定了url進(jìn)入規(guī)則,只有以/api/開頭的url才能進(jìn)入到此過濾器中。在doFilter方法中使用了自定義的ResponseWrapper對response進(jìn)行封裝。Controller接口走完之后獲取到接口返回的數(shù)據(jù)并再次封裝到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中的數(shù)據(jù)強(qiáng)制輸出到WapperedResponse的buffer里面,否則取不到數(shù)據(jù)
byte[] bytes = buffer.toByteArray();
try {
return new String(bytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
return "";
}
}
//內(nèi)部類,對ServletOutputStream進(jìn)行包裝,指定輸出流的輸出端
private class WapperedOutputStream extends ServletOutputStream {
private ByteArrayOutputStream bos = null;
public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException {
bos = stream;
}
//將指定字節(jié)寫入輸出流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錯誤的問題就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java實現(xiàn)分解任意輸入數(shù)的質(zhì)因數(shù)算法示例
這篇文章主要介紹了Java實現(xiàn)分解任意輸入數(shù)的質(zhì)因數(shù)算法,涉及java數(shù)學(xué)運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下2017-10-10
springboot整合gateway實現(xiàn)網(wǎng)關(guān)功能的示例代碼
本文主要介紹了springboot整合gateway實現(xiàn)網(wǎng)關(guān)功能的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02
RabbitMQ交換機(jī)使用場景和消息可靠性總結(jié)分析
這篇文章主要為大家介紹了RabbitMQ交換機(jī)使用場景和消息可靠性總結(jié)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
Java--SSH,SSM和Spring?Boot框架區(qū)別及優(yōu)缺點(diǎn)說明
這篇文章主要介紹了Java--SSH,SSM和Spring?Boot框架區(qū)別及優(yōu)缺點(diǎn)說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12

