java專案全域性異常攔截
java專案通常是由多人合作開發,但每個人的水平和想法又不一樣,在開發中並不能有效的避免所有異常都能夠有效的捕捉並處理,所以我們需要一個全域性的異常攔截處理,只需要配置一個攔截器即可。
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.support.spring.FastJsonJsonView;
import com.bingchuangapi.common.constant.Constants;
@Component
public class SpringHandlerExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
ModelAndView mv = new ModelAndView();
/* 使用FastJson提供的FastJsonJsonView檢視返回,不需要捕獲異常 */
FastJsonJsonView view = new FastJsonJsonView();
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(Constants.RET_CODE, "111");
attributes.put(Constants.RET_MSG, "伺服器異常,請稍後再試");
view.setAttributesMap(attributes);
mv.setView(view);
ex.printStackTrace();
return mv;
}
}
<bean id="exceptionHandler" class="com.bingchuangapi.common.base.SpringHandlerExceptionResolver" />
但這樣我們只知道有異常,如果有人捕捉了異常,但沒有把異常打印出來,在我們看日誌的時候會非常蛋疼,明明有問題但日誌中沒法體現出來,此時只需要寫一個aop即可
import java.text.SimpleDateFormat;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.springframework.aop.ThrowsAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
public class AspectService implements ThrowsAdvice
{
Logger logger=Logger.getLogger(AspectService.class);
//配置丟擲異常後通知,使用在方法aspect()上註冊的切入點
public void afterThrow(JoinPoint joinPoint, Exception ex){
logger.info("進入切面AfterThrowing方法中...");
//判斷日誌輸出級別
if(logger.isInfoEnabled()){
logger.info("afterThrow " + joinPoint + "\t" + ex.getMessage());
}
//詳細錯誤資訊
String errorMsg = "";
StackTraceElement[] trace = ex.getStackTrace();
for (StackTraceElement s : trace) {
errorMsg += "\tat " + s + "\r\n";
}
//寫入異常日誌
writeLog(errorMsg,joinPoint,ex);
}
/**
*
* @param detailErrMsg 詳細錯誤資訊
* @param method 方法名稱
* @Description: 日誌異常
* @author: Ma
* @createTime: 2016-10-14
*/
public void writeLog(String detailErrMsg,JoinPoint joinPoint,Exception ex){
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.
getRequestAttributes()).getRequest();
//獲取請求的URL
StringBuffer requestURL = request.getRequestURL();
//獲取參 數資訊
String queryString = request.getQueryString();
//封裝完整請求URL帶引數
if(queryString != null){
requestURL .append("?").append(queryString);
}
String cla=joinPoint.getTarget().getClass().getName();//action
String method=joinPoint.getSignature().getName();//method
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//FileOutputStream out=new FileOutputStream(file,false); //如果追加方式用true
//日誌具體引數
StringBuffer sb=new StringBuffer();
sb.append("-----------"+sdf.format(new Date())+"------------\r\n");
sb.append("遠端請求URL["+requestURL+"]\r\n");
sb.append("介面方法:["+cla+"."+method+"]\r\n");
sb.append("詳細錯誤資訊:"+ex+"\r\n");
sb.append(detailErrMsg+"\r\n");
}
}
配置如下
<!-- 啟用自動代理功能 -->
<aop:aspectj-autoproxy proxy-target-class="false"/>
<!-- 系統服務元件的切面Bean -->
<bean id="aspectService" class="com.**.log.AspectService"></bean>
<!-- AOP配置 -->
<aop:config>
<!-- 宣告一個切面,並注入切面Bean,相當於@Aspect -->
<aop:aspect id="simpleAspect" ref="aspectService">
<!-- 配置一個切入點,相當於@Pointcut -->
<aop:pointcut expression="execution(* com.***.common..*(..))" id="simplePointcut"/>
<aop:after-throwing pointcut-ref="simplePointcut" method="afterThrow" throwing="ex"/>
</aop:aspect>
</aop:config>