package com.smartmap.sample.ch1.controller.view; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.web.ErrorProperties; import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController; import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver; import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; import org.springframework.boot.web.servlet.error.ErrorAttributes; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.fasterxml.jackson.databind.ObjectMapper; @Controller public class ErrorViewController extends AbstractErrorController { final Log log = LogFactory.getLog(ErrorViewController.class); ErrorProperties errorProperties; @Autowired ObjectMapper objectMapper; public ErrorViewController() { super(new DefaultErrorAttributes()); } public ErrorViewController(ErrorAttributes errorAttributes, ErrorProperties errorProperties, List<ErrorViewResolver> errorViewResolvers) { super(errorAttributes, errorViewResolvers); this.errorProperties = errorProperties; } @Override public String getErrorPath() { return errorProperties.getPath(); } @RequestMapping("/error") public ModelAndView getErrorInfo(HttpServletRequest request, HttpServletResponse response) { Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(request, false)); Throwable cause = this.getCause(request); int status = (Integer) model.get("status"); String message = (String) model.get("message"); String errorMessage = getErrorMessage(cause); log.info(status + "," + message, cause); response.setStatus(status); if (!isJsonRequest(request)) { ModelAndView modelAndView = new ModelAndView(); modelAndView.addAllObjects(model); modelAndView.addObject("errorMessage", errorMessage); modelAndView.addObject("status", status); modelAndView.addObject("cause", cause); return modelAndView; } else { Map<String, Object> error = new HashMap(); error.put("errorMessage", errorMessage); error.put("status", status); error.put("cause", cause); writeJson(response, error); return null; } } protected Throwable getCause(HttpServletRequest request) { Throwable error = (Throwable) request.getAttribute("javax.servlet.error.exception"); if (error != null) { while (error instanceof ServletException && error.getCause() != null) { error = ((ServletException) error).getCause(); } } return error; } protected void writeJson(HttpServletResponse response, Map error) { response.setContentType("application/json;charset=utf-8"); try { response.getWriter().write(objectMapper.writeValueAsString(error)); } catch (IOException e) { // ignore } } protected String getErrorMessage(Throwable ex) { /* 不给前端显示详细错误 */ return "服务器错误,请联系管理员"; } protected boolean isJsonRequest(HttpServletRequest request) { return request.getHeader("Accept").contains("application/json"); } }