国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

SpringMVC的Controller攔截日志配置

smartlion / 2231人閱讀

摘要:如果處理除了問題,也要返回顯示錯誤的。用上就方便多了,加一個攔截類,加一點配置,就可以搞定所有。其他配置根據情況添加。采用這種方法,實現了對所有方法進行統一的日志記錄。

在項目中一直使用SpringMVC做Java后臺服務,返回的基本都是JSON。
要求請求參數、返回結果都要打印到log里,方便追蹤。
如果處理除了問題,也要返回顯示錯誤的JSON。

如果不用AOP攔截,每個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();
    }
}

很煩,都是重復的東西。用上AOP就方便多了,加一個攔截類,加一點配置,就可以搞定所有。

首先,添加Maven依賴:


  org.aspectj
  aspectjweaver
  1.8.0

然后,實現一個請求攔截處理類(Logger的方法被簡化了)

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;
/**
 * 請求攔截處理類
 * 
 * 
 */
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 "";
        }
        // 請求參數日志信息
        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("	", " ");
    }
}

這里用一個類實現了org.aopalliance.intercept.MethodInterceptor接口,實現invoke方法,達到對Controller方法的進入和返回攔截的效果。

注意要在適當的時機執行invocation.proceed()方法,并返回它的返回值。否則所有Controller方法都沒返回了。
還有一點,由于我用的SpringMVC,controller方法的一些參數并不需要打印出來,比如BingdingResult ModelMap Model等等。

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

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


    
     
           
         
    

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

這樣的話,開頭的代碼就可以簡化為:

@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);
}

只管業務就可以了,代碼清晰了很多。

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


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


    springmvc
    /*

注意跟業務的bean定義分離開。

采用這種方法,實現了對所有controller方法進行統一的日志記錄。
包括進入記錄:類名方法名,參數。返回記錄:返回值。異常處理返回并記錄StackTrace。
同時,使用一個簡單的ServiceException可以做到統一扔給Interceptor進行處理。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/65291.html

相關文章

  • SpringMVC【校驗器、統一處理異常、RESTful、攔截器】

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

    marser 評論0 收藏0
  • springboot學習(二)——springmvc配置使用

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

    hiyayiji 評論0 收藏0
  • 從SpringBoot到SpringMVC

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

    xavier 評論0 收藏0
  • Spring Boot實踐——三種攔截創建

    摘要:中的攔截器在開發中,攔截器是經常用到的功能。該攔截器只能過濾請求,允許多個攔截器同時存在,通過攔截器鏈管理。當時不再執行后續的攔截器鏈及被攔截的請求。實現攔截器大致也分為兩種,一種是實現接口,另一種利用的注解或配置。 Spring中的攔截器   在web開發中,攔截器是經常用到的功能。它可以幫我們驗證是否登陸、權限認證、數據校驗、預先設置數據以及統計方法的執行效率等等。今天就來詳細的談...

    fnngj 評論0 收藏0
  • SpringMVC入門筆記

    摘要:簡介注解用于修飾的方法,根據的的內容,通過適當的轉換為客戶端需要格式的數據并且寫入到的數據區,從而不通過視圖解析器直接將數據響應給客戶端。并且這些解析器都實現了接口,在接口中有四個最為主要的接口方法。 SpringMVC 細節方面的東西很多,所以在這里做一篇簡單的 SpringMVC 的筆記記錄,方便以后查看。 Spring MVC是當前最優秀的MVC框架,自從Spring 2.5版本...

    gekylin 評論0 收藏0

發表評論

0條評論

smartlion

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<