1. 程式人生 > 程式設計 >解決使用@ResponseBody後返回500錯誤的問題

解決使用@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,BlackParams params) {
 //Map<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);*/
 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錯誤的問題就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。