亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

SpringMVC的Controller攔截日志配置

smartlion / 2412人閱讀

摘要:如果處理除了問題,也要返回顯示錯(cuò)誤的。用上就方便多了,加一個(gè)攔截類,加一點(diǎn)配置,就可以搞定所有。其他配置根據(jù)情況添加。采用這種方法,實(shí)現(xiàn)了對(duì)所有方法進(jìn)行統(tǒng)一的日志記錄。

在項(xiàng)目中一直使用SpringMVC做Java后臺(tái)服務(wù),返回的基本都是JSON。
要求請(qǐng)求參數(shù)、返回結(jié)果都要打印到log里,方便追蹤。
如果處理除了問題,也要返回顯示錯(cuò)誤的JSON。

如果不用AOP攔截,每個(gè)Controller方法都要寫成類似如下的樣子:

@RequestMapping(value = "/someUrl", produces = { "application/json;charset=UTF-8" })
@ResponseBody
public String someUrl(@ModelAttribute ReqForm reqParams) {
    Logger.info(..., "someUrl request: "+JsonUtil.toJson(reqParams));
    // form validation ...
    try {
        ResultObject result = someService.serviceMethod(reqParams);
        Logger.info(..., "someUrl response: "+JsonUtil.toJson(result));
        return JsonResult.success(result);
    } catch (Exception e) {
        Logger.error(..., "someUrl: "
                + JsonUtil.toJson(reqParams) + " || " + ExceptionUtil.printStackTraceToString(e));
        return JsonResult.fail();
    }
}

很煩,都是重復(fù)的東西。用上AOP就方便多了,加一個(gè)攔截類,加一點(diǎn)配置,就可以搞定所有。

首先,添加Maven依賴:


  org.aspectj
  aspectjweaver
  1.8.0

然后,實(shí)現(xiàn)一個(gè)請(qǐng)求攔截處理類(Logger的方法被簡(jiǎn)化了)

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
/**
 * 請(qǐng)求攔截處理類
 * 
 * 
 */
public class ControllerInterceptor implements MethodInterceptor {
    @Override
    public String invoke(MethodInvocation invocation) {
        String result = "";
        String paramsStr = "";
        Object value = null;
        Method md = invocation.getMethod();
        try {
            Object[] args = invocation.getArguments();
            paramsStr = this.logRequest(args);
            value = invocation.proceed();
        } catch (Throwable e) {
            if (e instanceof ServiceException) {
                Logger.error(..., ((ServiceException) e).getAlarmId(), md
                        .getDeclaringClass().getSimpleName()
                        + "."
                        + md.getName()
                        + " || "
                        + paramsStr
                        + " || "
                        + printStackTraceToString(e));
            } else {
                Logger.error(..., "some_alarm_id", md
                        .getDeclaringClass().getSimpleName()
                        + "."
                        + md.getName()
                        + " || "
                        + paramsStr
                        + " || "
                        + printStackTraceToString(e));
            }
        }
        if (value != null) {
            result = value.toString();
        } else {
            result = JsonResult.SYSERROR;
        }
        this.logRequestResponse(md, paramsStr, result);
        return result;
    }
    private String logRequest(Object[] args) {
        if (args == null) {
            return "";
        }
        // 請(qǐng)求參數(shù)日志信息
        Map params = new HashMap();
        int i = 1;
        for (Object arg : args) {
            if (!(arg instanceof BindingResult) && !(arg instanceof ModelMap) && !(arg instanceof Model)) {
                if (arg instanceof HttpServletRequest) {
                    HttpServletRequest httpRequest = (HttpServletRequest) arg;
                    Enumeration enume = httpRequest.getParameterNames();
                    if (null != enume) {
                        Map hpMap = new HashMap();
                        while (enume.hasMoreElements()) {
                            Object element = enume.nextElement();
                            if (null != element) {
                                String paramName = (String) element;
                                String paramValue = httpRequest.getParameter(paramName);
                                hpMap.put(paramName, paramValue);
                            }
                        }
                        params.put("HttpServletRequest", hpMap);
                    }
                } else {
                    try {
                        params.put("arg" + i, JsonUtil.toJson(arg));
                        i++;
                    } catch (Throwable e) {
                        Logger.warn(..., "CANNOT trasform to json string:"
                                + arg.getClass().getName());
                    }
                }
            }
        }
        String paramsStr = JsonUtil.toJson(params);
        return paramsStr;
    }
    private void logRequestResponse(Method md, String paramsStr, String re) {
        Map logMap = new HashMap();
        logMap.put("controller.method", md.getDeclaringClass().getSimpleName() + "." + md.getName());
        logMap.put("logReq", paramsStr);
        logMap.put("logRes", re);
        Logger.info(..., logMap);
    }
    private String printStackTraceToString(Throwable e) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        e.printStackTrace(pw);
        return sw.toString().replace("
", " ").replace("
", " ").replace("	", " ");
    }
}

這里用一個(gè)類實(shí)現(xiàn)了org.aopalliance.intercept.MethodInterceptor接口,實(shí)現(xiàn)invoke方法,達(dá)到對(duì)Controller方法的進(jìn)入和返回?cái)r截的效果。

注意要在適當(dāng)?shù)臅r(shí)機(jī)執(zhí)行invocation.proceed()方法,并返回它的返回值。否則所有Controller方法都沒返回了。
還有一點(diǎn),由于我用的SpringMVC,controller方法的一些參數(shù)并不需要打印出來,比如BingdingResult ModelMap Model等等。

如果有HttpServletRequest傳進(jìn)來,也不能直接被JSON序列化,需要特殊處理一下。還有其他不能序列化的東西,直接略掉(代碼中的try…catch)。

然后,配置下spring。
spring-mvc.xml文件的標(biāo)簽中加入aop相應(yīng)的schema,并且添加剛才寫的攔截類bean。


    
     
           
         
    

上主要添加xmlns:aopxsi:schemaLocation兩端aop的配置。其他配置根據(jù)情況添加。
切面配置的含義是:在your.controller.package下面所有類所有public的,任何參數(shù),任何返回類型的方法進(jìn)行攔截。

這樣的話,開頭的代碼就可以簡(jiǎn)化為:

@RequestMapping(value = "/someUrl", produces = { "application/json;charset=UTF-8" })
@ResponseBody
public String someUrl(@ModelAttribute ReqForm reqParams) {
    // form validation ...
    ResultObject result = someService.serviceMethod(reqParams);
    return JsonResult.success(result);
}

只管業(yè)務(wù)就可以了,代碼清晰了很多。

最后,要注意在web.xml中springMVC的配置,類似于:


    springmvc
    org.springframework.web.servlet.DispatcherServlet
    
        contextConfigLocation
        classpath:/spring/spring-mvc.xml
    
    1


    springmvc
    /*

注意跟業(yè)務(wù)的bean定義分離開。

采用這種方法,實(shí)現(xiàn)了對(duì)所有controller方法進(jìn)行統(tǒng)一的日志記錄。
包括進(jìn)入記錄:類名方法名,參數(shù)。返回記錄:返回值。異常處理返回并記錄StackTrace。
同時(shí),使用一個(gè)簡(jiǎn)單的ServiceException可以做到統(tǒng)一扔給Interceptor進(jìn)行處理。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/65291.html

相關(guān)文章

  • SpringMVC【校驗(yàn)器、統(tǒng)一處理異常、RESTful、攔截器】

    摘要:只要有一個(gè)攔截器不放行,不能執(zhí)行完成號(hào)不放行和號(hào)不放行測(cè)試結(jié)果總結(jié)只有前邊的攔截器方法放行,下邊的攔截器的才執(zhí)行。至于他們的攔截器鏈的調(diào)用順序,和的是沒有差別的。 前言 本博文主要講解的知識(shí)點(diǎn)如下: 校驗(yàn)器 統(tǒng)一處理異常 RESTful 攔截器 Validation 在我們的Struts2中,我們是繼承ActionSupport來實(shí)現(xiàn)校驗(yàn)的...它有兩種方式來實(shí)現(xiàn)校驗(yàn)的功能 手寫...

    marser 評(píng)論0 收藏0
  • springboot學(xué)習(xí)(二)——springmvc配置使用

    摘要:中添加攔截器配置如下攔截所有請(qǐng)求,也就是,只攔截開頭的請(qǐng)求。在中并沒有提供配置文件的方式來配置攔截器,因此需要使用的代碼式配置,配置如下這個(gè)屬性通常并不需要手動(dòng)配置,高版本的會(huì)自動(dòng)檢測(cè)第四點(diǎn)講下靜態(tài)資源映射。 以下內(nèi)容,如有問題,煩請(qǐng)指出,謝謝 上一篇講解了springboot的helloworld部分,這一篇開始講解如何使用springboot進(jìn)行實(shí)際的應(yīng)用開發(fā),基本上尋著sprin...

    hiyayiji 評(píng)論0 收藏0
  • 從SpringBoot到SpringMVC

    摘要:概述用久了,深受其約定大于配置的便利性毒害之后,我想回歸到時(shí)代,看看開發(fā)模式中用戶是如何參與的。備注當(dāng)然本文所使用的全是非注解的配置方法,即需要在中進(jìn)行配置并且需要遵循各種實(shí)現(xiàn)原則。而更加通用主流的基于注解的配置方法將在后續(xù)文章中詳述。 showImg(https://segmentfault.com/img/remote/1460000015244684); 概述 用久了Sprin...

    xavier 評(píng)論0 收藏0
  • Spring Boot實(shí)踐——三種攔截創(chuàng)建

    摘要:中的攔截器在開發(fā)中,攔截器是經(jīng)常用到的功能。該攔截器只能過濾請(qǐng)求,允許多個(gè)攔截器同時(shí)存在,通過攔截器鏈管理。當(dāng)時(shí)不再執(zhí)行后續(xù)的攔截器鏈及被攔截的請(qǐng)求。實(shí)現(xiàn)攔截器大致也分為兩種,一種是實(shí)現(xiàn)接口,另一種利用的注解或配置。 Spring中的攔截器   在web開發(fā)中,攔截器是經(jīng)常用到的功能。它可以幫我們驗(yàn)證是否登陸、權(quán)限認(rèn)證、數(shù)據(jù)校驗(yàn)、預(yù)先設(shè)置數(shù)據(jù)以及統(tǒng)計(jì)方法的執(zhí)行效率等等。今天就來詳細(xì)的談...

    fnngj 評(píng)論0 收藏0
  • SpringMVC入門筆記

    摘要:簡(jiǎn)介注解用于修飾的方法,根據(jù)的的內(nèi)容,通過適當(dāng)?shù)霓D(zhuǎn)換為客戶端需要格式的數(shù)據(jù)并且寫入到的數(shù)據(jù)區(qū),從而不通過視圖解析器直接將數(shù)據(jù)響應(yīng)給客戶端。并且這些解析器都實(shí)現(xiàn)了接口,在接口中有四個(gè)最為主要的接口方法。 SpringMVC 細(xì)節(jié)方面的東西很多,所以在這里做一篇簡(jiǎn)單的 SpringMVC 的筆記記錄,方便以后查看。 Spring MVC是當(dāng)前最優(yōu)秀的MVC框架,自從Spring 2.5版本...

    gekylin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<