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

网友投稿 624 2022-11-22


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

在springmvc+mybatis的项目中,利用mybatis分页插件mybatis-paginator进行分页查询,结果出现了500异常,后端又没有明显的报错。

原来的写法,返回Map对象,由springmvc里面的机制转为json对象,这样就会导致,在转json过程中的报错,都隐藏了,无法抛出,前端获取不到正确的数据,

最后就出现了500的异常。

@RequestMapping(value = "/query")

@ResponseBody

public Map data(HttpServletRequest request, HttpServletResponse response, CreditloanInfoParams params) {

Map data = new HashMap();

if(params==null){

params=new CreditloanInfoParams();

}

PageList list = (PageList) creditloanInfoService.getCreditloanInfoLhttp://istData(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 data = new HashMap();

/*PageList blackDatas = (PageList

data.put("total", blackDatas.getPaginator().getTotalCount());

data.put("rows", blackDatas);*/

//blackService.getPageData(params);

/* Map data = nhttp://ew HashMap();

PageList blackDatas = blackService.getBlackListData(params);

data.put("total", blackDatas.getPaginator().getTotalCount());

data.pufPVcjAsvObt("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

}

}

}

data.put("total", blackDatas.getPaginator().getTotalCount());

data.put("rows", blackDatas);*/

//blackService.getPageData(params);

/* Map data = nhttp://ew HashMap();

PageList blackDatas = blackService.getBlackListData(params);

data.put("total", blackDatas.getPaginator().getTotalCount());

data.pufPVcjAsvObt("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

}

}

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:使用maven工具解决jar包冲突或重复加载的问题
下一篇:Java Unsafe类实现原理及测试代码
相关文章

 发表评论

暂时没有评论,来抢沙发吧~