zoukankan      html  css  js  c++  java
  • 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();
        }
    }
  • 相关阅读:
    Python之旅.第九章.并发编程.
    Python之旅.第九章.并发编程。
    Python之旅.第九章.并发编程..
    Python之旅.第九章.并发编程
    Python之旅.第九章.并发编程
    animate.css
    JS对于Android和IOS平台的点击响应的适配
    腾讯设计导航
    炫酷照片墙----------------网站也不错的样子
    判断设备是电脑还是手机
  • 原文地址:https://www.cnblogs.com/zhanghaoh/p/5388386.html
Copyright © 2011-2022 走看看