话不多说,直接上代码:
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @FileNName: BaseController
* @Description: 全局统一处理controller
* @Author: guoxingliang
* @Create: 2019-08-06 10:08
* @Copyright: (c)2018年 ***公司
*/
@Slf4j
@ControllerAdvice
public class BaseController {
// 专门用来捕获和处理Controller层的校验时异常
@ExceptionHandler(VerifyException.class)
public ModelAndView verifyExceptionHandler(VerifyException e, HttpServletRequest request) {
this.exceptionLogs(e, request);
ModelAndView mv = new ModelAndView(new MappingJackson2JsonView());
mv.addObject("code", ApiResult.ERROR_VALUE);
mv.addObject("msg",e.getMessage());
mv.addObject("data",null);
return mv;
}
// 专门用来捕获和处理Controller层的异常
@ExceptionHandler(Exception.class)
public ModelAndView exceptionHandler(Exception e, HttpServletRequest request) {
this.exceptionLogs(e, request);
ModelAndView mv = new ModelAndView(new MappingJackson2JsonView());
mv.addObject("code", ApiResult.ERROR_SYSTEM);
mv.addObject("msg", LanguageUtil.get(ConstantsUtils.FAIL_MSG));
mv.addObject("data",null);
return mv;
}
public void exceptionLogs(Exception e, HttpServletRequest request) {
try{
//日志打印
log.error("BaseController->exceptionHandler:request url:[{}],request params:[{}];exception:[{}]", request.getRequestURI(), RequestUtils.getRequestJsonString(request), e);
} catch (IOException ex) {
log.error("BaseController getting parameter exceptions");
}
}
}
用到的工具类:
import org.springframework.util.StringUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class RequestUtils {
private RequestUtils() {}
private static final String UNKNOWN = "unknown";
public static String getRequestJsonString(HttpServletRequest request) throws IOException {
String method = request.getMethod();
if (method.equals("GET")) {
if (StringUtils.isEmpty(request.getQueryString())) {
return null;
}
return new String(request.getQueryString().getBytes("iso-8859-1"), "utf-8").replaceAll("%22", "\"");
} else {
return getRequestPostStr(request);
}
}
public static String getRequestPostStr(HttpServletRequest request) throws IOException {
byte[] buffer = getRequestPostBytes(request);
String charEncoding = request.getCharacterEncoding();
if (charEncoding == null) {
charEncoding = "UTF-8";
}
return new String(buffer, charEncoding);
}
public static byte[] getRequestPostBytes(HttpServletRequest request) throws IOException {
int contentLength = request.getContentLength();
if (contentLength < 0) {
return null;
}
byte[] buffer = new byte[contentLength];
for (int i = 0; i < contentLength; ) {
int readLen = request.getInputStream().read(buffer, i, contentLength - i);
if (readLen == -1) {
break;
}
i += readLen;
}
return buffer;
}
public static String getCookie(HttpServletRequest request, String name) {
Cookie[] cookies = request.getCookies();
for (Cookie cookie: cookies){
if(cookie.getName().equals(name))
return cookie.getValue();
}
return "";
}
}
其中VerifyException是自定义的异常
大家都说post打印参数出现了问题,其实问题原因主要是由于request.getInputStream()在@Responsebody使用之后会自动关闭,导致日志打印时出现request stream close问题,以至于post参数无法打印,这里给大家提供一个解决办法
重写request构造方法,进行request缓存
代码如下:
新增类BodyReaderHttpServletRequestWrapper.java
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] body;
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
body = readBytes(request.getInputStream());
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
}
public static byte[] readBytes(InputStream is) throws Exception {
byte[] buffer=new byte[1024];
int len=0;
ByteArrayOutputStream bos=new ByteArrayOutputStream();
while((len=is.read(buffer))!=-1){
bos.write(buffer,0,len);
}
bos.flush();
return bos.toByteArray();
}
}
新增类:
@WebFilter(filterName = "httpServletRequestReplacedFilter", urlPatterns = "/*")
public class HttpServletRequestReplacedFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
ServletRequest requestWrapper = null;
if (request instanceof HttpServletRequest) {
requestWrapper = new BodyReaderHttpServletRequestWrapper((HttpServletRequest) request);
}
if (requestWrapper == null) {
chain.doFilter(request, response);
} else {
chain.doFilter(requestWrapper, response);
}
}
@Override
public void destroy() {
}
}
最后在Application中加入注解:@ServletComponentScan
再次打印,发现问题解决