dubbo解决参数拦截问题

解决token拦截问题

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import mellson.common.ContantSession;
import mellson.common.PasRight;
import mellson.p1corp.domain.accesstoken.Accesstoken;
import mellson.p1corp.domain.app.App;
import mellson.p1corp.domain.estore.Estore;
import mellson.p1corp.domain.token.Token;
import mellson.p1corp.rest.accesstoken.AccesstokenRESTService;
import mellson.p1corp.rest.app.AppRESTService;
import mellson.p1corp.rest.companyLoginInfo.CompanyLoginInfoRESTService;
import mellson.p1corp.rest.estore.EstoreRESTService;
import mellson.p1corp.rest.login.LoginRESTService;
import mellson.p1corp.rest.memberrightmanagement.MemberRightManagementRESTService;
import mellson.p1tools.common.GlobalConstant;
import mellson.p1tools.common.RedisConstant;
import mellson.p1tools.domain.token.Admintoken;
import mellson.p1tools.domain.token.Custoken;
import mellson.p1tools.domain.token.Thetoken;
import mellson.p1tools.util.MyException;
import mellson.r5crm.rest.login.CusLoginRESTService;
import mellson.redis.rest.RedisRESTService;

@Component
public class AuthInterceptor implements HandlerInterceptor {
private static Logger logger = LoggerFactory.getLogger(AuthInterceptor.class);

@DubboReference
private AccesstokenRESTService accesstokenRESTService;


@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {
    // 如果不是映射到方法直接通过
    if (!(handler instanceof HandlerMethod)) {
        return true;
    }
    HandlerMethod handlerMethod = (HandlerMethod) handler;
    Method method = handlerMethod.getMethod();
    String requestPath = request.getRequestURI();
    logger.debug("Method: " + method.getName() + ", IgnoreSecurity: "
            + method.isAnnotationPresent(IgnoreSecurity.class));
    logger.debug("requestPath: " + requestPath);
    if (null != ContantSession.getIgnoreRequestPath()) {
        for(String tmp : ContantSession.getIgnoreRequestPath()) {
            if(requestPath.startsWith(tmp)) {
                return true;
            }
        }

    }
    /*if (requestPath.contains("/error")) {
        return true;
    }*/
    if (method.isAnnotationPresent(IgnoreSecurity.class)) {
        return true;
    }
    if(isAllTokenNull(request)) {
        if(appInterceptor(request, response)) {
            return true;
        }
        if(estoreInterceptor(request, response)) {
            return true;
        }
    }
thetoken.setTokentype(GlobalConstant.custoken);
                        thetoken.setTokenvalue(custoken);
   
    } else {
        throw new MyException("token-isnull");
    }
}

}

}

拦截注解

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Auth {

}

参数拦截转换

import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.multipart.support.MissingServletRequestPartException;
import mellson.p1tools.domain.token.Thetoken;

public class ThetokenMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().isAssignableFrom(Thetoken.class)
&& parameter.hasParameterAnnotation(Auth.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
Thetoken thetoken = (Thetoken) webRequest.getAttribute(“thetoken”, RequestAttributes.SCOPE_REQUEST);
if (thetoken != null) {
return thetoken;
}
throw new MissingServletRequestPartException(“thetoken”);
}
}

安全过滤注解

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface IgnoreSecurity {

}

dubbo整合spring boot

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableDubbo
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

解决跨域问题,还有参数拦截问题

import java.util.ArrayList;
import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;

/**

  • classpath路径:locations={“classpath:application-bean1.xml”,”classpath:application-bean2.xml”}
  • file路径: locations ={“file:d:/test/application-bean1.xml”}; */

@Configuration
@ImportResource(locations={“classpath:conf/myapplication.xml”})
//@EnableWebMvc
public class ConfigClass implements WebMvcConfigurer {

/**
 * 解决跨域问题
 * @return
 */
@Bean
public CorsFilter corsFilter() {
   final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
   final CorsConfiguration corsConfiguration = new CorsConfiguration();
   corsConfiguration.setAllowCredentials(true);
   corsConfiguration.addAllowedOrigin("*");
   corsConfiguration.addAllowedHeader("*");
   corsConfiguration.addAllowedMethod("*");
   urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
   return new CorsFilter(urlBasedCorsConfigurationSource);

}

//关键,将拦截器作为bean写入配置中
@Bean
public AuthInterceptor getAuthInterceptor(){
    return new AuthInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
    // 注册拦截器,配置拦截的路径
    registry.addInterceptor(getAuthInterceptor()).addPathPatterns("/**");
    // 配置不拦截的路径
    // ir.excludePathPatterns("**/swagger-ui.html");
    // 还可以在这里注册其它的拦截器
    //registry.addInterceptor(new OtherInterceptor()).addPathPatterns("/**");
}

@Bean
public ThetokenMethodArgumentResolver thetokenMethodArgumentResolver() {
    return new ThetokenMethodArgumentResolver();
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
    argumentResolvers.add(thetokenMethodArgumentResolver());

}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    //创建fastJson消息转换器
    FastJsonHttpMessageConverter fastjsonConverter = new FastJsonHttpMessageConverter();
    //创建配置类
    FastJsonConfig fastJsonConfig = new FastJsonConfig();
    //修改配置返回内容的过滤
    fastJsonConfig.setSerializerFeatures(
            SerializerFeature.DisableCircularReferenceDetect
    );
    fastjsonConverter.setFastJsonConfig(fastJsonConfig);
    MediaType jsonUtf8 = MediaType.APPLICATION_JSON;
    List<MediaType> medias = new ArrayList<>();
    medias.add(jsonUtf8);
    fastjsonConverter.setSupportedMediaTypes(medias);
    //将fastjson添加到视图消息转换器列表内
    converters.add(fastjsonConverter);
}

}

dubbo调用拦截扩展

动态调用数据源的示例

package com.test

import com.alibaba.dubbo.rpc.Filter;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcException;

import mellson.multidata.SpObserver;

public class DubboFilter implements Filter {

@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
    if(null!=invocation.getArguments()){
        for(Object tmp : invocation.getArguments()){
            SpObserver.putSp(tmp.toString());
            return invoker.invoke(invocation);
        }
    }else{
        SpObserver.putSp("p1");
    }
    return invoker.invoke(invocation);
}

}

在META-INF增加配置文件,文本格式即可

里面内容

xxx=com.xxx.XxxFilter
xxx是过滤器名称,com.xxx.XxxFilter完整的类名
修改服务方的配置
<!-- 提供方调用过程缺省拦截器,将拦截所有service -->
<dubbo:provider filter="xxx"/>

支持多种配置方式
<!-- 消费方调用过程拦截 -->
<dubbo:reference filter="xxx,yyy" />
<!-- 消费方调用过程缺省拦截器,将拦截所有reference -->
<dubbo:consumer filter="xxx,yyy"/>
<!-- 提供方调用过程拦截 -->
<dubbo:service filter="xxx,yyy" />
<!-- 提供方调用过程缺省拦截器,将拦截所有service -->
<dubbo:provider filter="xxx,yyy"/>
resources
        |-META-INF
            |-dubbo
                |-org.apache.dubbo.rpc.Filter