为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和项目调用的类型;

posted @ 2017-03-28 17:13  growthofmonkey  阅读(3316)  评论(0编辑  收藏  举报