zoukankan      html  css  js  c++  java
  • 为webService添加Interceptor(拦截器)

    今天写一个简单的拦截器,以webService接口为例:

    背景:H5的一个项目,只要调用H5webService 接口下面的方法都会触发一个AuthorityInterceptor去验证是否调用类型是H5,session是否失效.

    1.需要自己定义一个Interceptor,我定义的Interceptor去验证调用类型moduleType和session:

    package com.lcc.h5.ws;
    
    import com.lcc.api.dto.session.SessionInfo;
    import com.lcc.api.exception.AccessDeniedException;
    import com.lcc.api.web.common.ModuleType;
    import com.lcc.logger.Logger;
    import com.lcc.logger.LoggerFactory;
    import com.lcc.service.BaseAuthorityService;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.cxf.interceptor.Fault;
    import org.apache.cxf.message.Message;
    import org.apache.cxf.phase.AbstractPhaseInterceptor;
    import org.apache.cxf.transport.http.AbstractHTTPDestination;
    
    import javax.servlet.http.HttpServletRequest;
    
    public class AuthorityInterceptor extends AbstractPhaseInterceptor<Message> {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(AuthorityInterceptor.class);
    
        private BaseAuthorityService authorityService;
    
        public AuthorityInterceptor(String phase) {
            super(phase);
        }
    
        public AuthorityInterceptor() {
            this("post-stream");
        }
    
        @Override
        public void handleMessage(Message message) throws Fault {
            Fault fault = new Fault(new AccessDeniedException("illeagl moduleType access"));
            fault.setStatusCode(421);
    
            HttpServletRequest httpRequest = (HttpServletRequest) message.get(AbstractHTTPDestination.HTTP_REQUEST);
            String sessionId = httpRequest.getHeader("Token");
            if (StringUtils.isBlank(sessionId)) {
                LOGGER.info("blank session");
                throw fault;
            }
            LOGGER.info("session authority, session id {}", sessionId);
    
            String moduleKey = httpRequest.getHeader("moduleType");
            if (StringUtils.isEmpty(moduleKey)) {
                LOGGER.info("moduleType is empty");
                throw fault;
            }
            ModuleType module = ModuleType.fromKey(moduleKey);
    
            SessionInfo sessionInfo = null;
            if (ModuleType.H5.equals(module)) {
                sessionInfo = authorityService.getSessionInfo(sessionId);
                if (sessionInfo == null) {
                    throw fault;
                }
            } else {
                throw fault;
            }
        }
    
        public void setAuthorityService(BaseAuthorityService authorityService) {
            this.authorityService = authorityService;
        }
    }

     上面Interceptor用到的java bean:

    public abstract class SessionInfo implements Serializable {
    
        private static final long serialVersionUID = 6544973626519192604L;
    
        private String key;
        // timestamp
        private Long createdAt;
        // unit: second
        private Long expiryTime;
    
        public String getKey() {
            return key;
        }
    
        public void setKey(String key) {
            this.key = key;
        }
    
        public Long getCreatedAt() {
            return createdAt;
        }
    
        public void setCreatedAt(Long createdAt) {
            this.createdAt = createdAt;
        }
    
        public Long getExpiryTime() {
            return expiryTime;
        }
    
        public void setExpiryTime(Long expiryTime) {
            this.expiryTime = expiryTime;
        }
    
        @Override
        public String toString() {
            return new StringBuilder().append("{key: ").append(key).append(", createdAt: ").append(createdAt)
                    .append(", expiryTime: ").append(expiryTime).append("}").toString();
        }
    }

     =====================

    为了防止别人恶意访问接口,我们可以给调用类型加密,内部调用直接传入加密后的String,在后台去转换验证即可.

    public enum ModuleType {
    
        H5("md5加密码");
    
        private String key;
    
        ModuleType(String key) {
            this.key = key;
        }
    
        public String getKey() {
            return key;
        }
    
    }
    BaseAuthorityService及其实现类 请参考http://www.cnblogs.com/cc-java/p/6625998.html
    2.Interceptor写好了,接下来就看下怎么在xml配置文件里面为webService配置Interceptor
       <bean id="authorityInterceptor" class="com.lcc.ws.AuthorityInterceptor" >
            <property name="authorityService" ref="authorityService" />
        </bean>
    
        <bean id="authorityService" class="com.lcc.authority.AuthorityService" >
            <property name="sessionTemplate" ref="redisSessionSerializationTemplate" />
        </bean>
    
        <bean id="h5WebService" class="com.lcc.ws.impl.H5WebService">
        </bean>
        <jaxrs:server id="h5WebServiceContainer"
                      address="/h5">
            <jaxrs:serviceBeans>
                <ref bean="h5WebService" />
            </jaxrs:serviceBeans>
    
            <jaxrs:providers>
                <ref bean="wadlGenerator" />
                 <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider">
                     <constructor-arg ref="handshakeJacksonMapper" />
                 </bean>
            </jaxrs:providers>
            
            <jaxrs:inInterceptors>
                <ref bean="fileSizeInterceptor" />
                <ref bean="authorityInterceptor" />
            </jaxrs:inInterceptors>
            <jaxrs:outInterceptors>
                <ref bean="outInterceptor" />
            </jaxrs:outInterceptors>
        </jaxrs:server>

    到这里就已经为h5WebService接口配置好AuthorityInterceptor拦截器了;只要访问这个接口都会先进入拦截器里面去验证session和项目调用的类型;

  • 相关阅读:
    luogu P4284 [SHOI2014]概率充电器 期望 概率 树形dp
    luogu P5161 WD与数列 SAM 线段树合并 启发式合并
    5.5 省选模拟赛 B Permutation 构造 贪心
    luogu P3761 [TJOI2017]城市 树的直径 bfs
    一本通 1783 矩阵填数 状压dp 容斥 计数
    CF R638 div2 F Phoenix and Memory 贪心 线段树 构造 Hall定理
    BSOJ 5445 -- 【2018雅礼】树 prufer序列 dp
    CF1037H Security 线段树合并 SAM
    c++11の顺序容器
    c++11の关联容器
  • 原文地址:https://www.cnblogs.com/cc-java/p/6635819.html
Copyright © 2011-2022 走看看