dubbox ExceptionMapper Filter request response 數據獲取 數據傳遞


dubbx雖然是基於jboss的resteasy實現restfull,但是對resteasy原生的配置卻不支持(可能是考慮到dubbo本事的設計模式及實現難度,但是和大部分framework的設計風格背道而馳),ExceptionMapper , Filter 和 Interceptor  需要配置在  <dubbo:protocol  extension="x,x"/> ,參考 http://dangdangdotcom.github.io/dubbox/rest.html

 

一.Filter

Filter主要用於訪問和設置HTTP請求和響應的參數、URI等等。例如,設置HTTP響應的cache header

 

1.ContainerRequestFilter 服務器端請求處理之前,一般用於取請求參數做一些處理,比如記錄access log,流量控制,權限校驗 等。

常用的幾個點:

使用 @Context 獲取 HttpServletRequest 等servlet內置對象。

和標准的web filter一樣,Spring @Autowired 無法使用,必須通過 WebApplicationContext 獲取Spring管理的bean。

數據傳遞使用 SecurityContext (本人能力有限,沒找到更好的方式)。

直接返回結果 requestContext.abortWith(response);特別注意,調用此方法后,如果繼續有其他code,下邊的code一樣會執行的。(java語言本身的限制)。

 

 

package com.leon.filter;

import java.io.IOException;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;

import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;


@Component
public class SecurityFilter implements ContainerRequestFilter{
    
    @Context
    private transient HttpServletRequest servletRequest;
    
    private SellerSecurityService sellerSecurityService;
    
    private AccessLogService accessLogService;
    
    private SellerPvService  sellerPvService;
    
    @Override
    public void filter(ContainerRequestContext requestContext)
            throws IOException {
        
           Date now=new Date();

           String appKey=HttpUtil.getParameterString(servletRequest,"appkey");
           
           if(StringUtil.isEmpty(appKey)){
               Response response=bulidUnauthResponse(Constant.missAppKeyResponse);
               requestContext.abortWith(response);
               return;
           }    
           
           getService();           

           AccessLog accessLog=new AccessLog();
           
           accessLogService.log(accessLog);
           
           SecurityContext securityContext=bulidSecurityContext("test");
           requestContext.setSecurityContext(securityContext);   
           
    }
    
    public static SecurityContext bulidSecurityContext(final String value){
        return new SecurityContext() {                
            @Override
            public boolean isUserInRole(String role) {
                return false;
            }
            @Override
            public boolean isSecure() {
                return false;
            }
            @Override
            public Principal getUserPrincipal() {
                return null;
            }
            @Override
            public String getAuthenticationScheme() {
                return value;
            }
        };
    }

    private Response  bulidUnauthResponse(String context){
                return Response.ok().status(Constant.unAuthCode).entity(context).build();
    }

    public void getService() {
        if(sellerSecurityService!=null){
            return;
        }
        WebApplicationContext wac=WebApplicationContextUtils.getWebApplicationContext(servletRequest.getServletContext());
        sellerSecurityService=wac.getBean(SellerSecurityService.class);
        accessLogService=wac.getBean(AccessLogService.class);
        sellerPvService=wac.getBean(SellerPvService.class);
    }

}

2.ContainerResponseFilter 請求處理完之后調用,通常用作裝入公共信息到 response

public class CacheControlFilter implements ContainerResponseFilter {

    public void filter(ContainerRequestContext req, ContainerResponseContext res) {
        if (req.getMethod().equals("GET")) {
            res.getHeaders().add("Cache-Control", "someValue");
        }
    }
}

 

 

 

二.Interceptor

Interceptor主要用於訪問和修改輸入與輸出字節流,例如,手動添加GZIP壓縮:

1.ReaderInterceptor 攔截 MessageBodyReader.readFrom 可以用來實現校驗

2.WriterInterceptor  攔截 MessageBodyWriter.writeTo 可以用來實現數據壓縮

public class GZIPWriterInterceptor implements WriterInterceptor {

    @Override
    public void aroundWriteTo(WriterInterceptorContext context)
                    throws IOException, WebApplicationException {
        OutputStream outputStream = context.getOutputStream();
        context.setOutputStream(new GZIPOutputStream(outputStream));
        context.proceed();
    }
}

 

三.ExceptionMapper 

用來自定義Exception的處理方式。必須繼承 ExceptionMapper<E extends Throwable>,泛型為處理的異常類型

package com.leon.exception;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

import org.apache.log4j.Logger;


public class ExceptionMapperSupport implements ExceptionMapper<Exception> {
    private static final Logger LOGGER = Logger
            .getLogger(ExceptionMapperSupport.class);

    /**
     * 異常處理
     * 
     * @param exception
     * @return 異常處理后的Response對象
     */
    @Override
    public Response toResponse(Exception exception){
        String response;
        int code;
        if(exception instanceof MyException){
            MyException myException=(MyException)exception;
            response="{\"resp_code\":\""+myException.getRespCode()+"\",\"resp_info\":\""+myException.getRespInfo()+"\"}";
            code=Constant.successCode;
        }else{
            response=Constant.errorResponse;
            LOGGER.error(exception.getMessage(), exception);
            code=Constant.errorCode;
        }
        return Response.ok(response, MediaType.APPLICATION_JSON).status(code)
                .build();
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM