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.htmlhtml

 

一.Filterjava

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

 

1.ContainerRequestFilter 服務器端請求處理以前,通常用於取請求參數作一些處理,好比記錄access log,流量控制,權限校驗 等。github

經常使用的幾個點:web

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

和標準的web filter同樣,Spring @Autowired 沒法使用,必須經過 WebApplicationContext 獲取Spring管理的bean。apache

數據傳遞使用 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 restful

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();
    }
}
相關文章
相關標籤/搜索