background

  • It has certain requirements for the security of the service interface, which requires signature verification.
  • Decrypt and restore the request parameters of the service interface;

Implementation logic

  • Custom filter implementationFilterAnd register toSpringBootIn the
  • By putting theServletRequestConvert to a custom wrapper for free readingInputStream
  • Decrypt and recombine parameters according to specific request method types and service parameter encryption requirements
  • Putting the new parameter request body into the wrapper produces a new oneInputStream
  • Pass in the wrapper and the response objectFilterChainFollow-up Services

Filter implementation code

/** * <p> * Parameter filter * </p> **@author zhengshangjin
 * @version 1.0.0
 * @since 1.0.0
 * created on 2020-04-03
 */
@Slf4j
@Component
public class ServerParamFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
      
      	// Convert a ServletRequest object into a custom wrapper object (see the article implementing a ServletRequest Stream repeat read, Stream rewrite scenario)
        CoverHttpServletRequest requestWrapper = new CoverHttpServletRequest((HttpServletRequest) request);

        // Do different arguments according to different request method types and return new wrappers
        if (HttpMethod.POST.matches(requestWrapper.getMethod())) {
            requestWrapper = handlePostCommonParam(requestWrapper);
        }
        if (HttpMethod.GET.matches(requestWrapper.getMethod())) {
            requestWrapper = handleGetCommonParam(requestWrapper);
        }
      
      	// Continue execution
        chain.doFilter(requestWrapper, response);
    }

    /** * handles the GET public argument **@paramRequestWrapper requestWrapper *@return CoverHttpServletRequest
     * @author zhengshangjin
     * created on 2020-04-03
     */
    public CoverHttpServletRequest handleGetCommonParam(CoverHttpServletRequest requestWrapper) {
      
      	// Business logic
        // The collated public parameters can be stored in RequestAttributes or ThreadLocal for subsequent calls
      
        return requestWrapper;
    }

    /** * Handles the POST public argument **@paramRequestWrapper requestWrapper *@return CoverHttpServletRequest
     * @author zhengshangjin
     * created on 2020-04-03
     */
    public CoverHttpServletRequest handlePostCommonParam(CoverHttpServletRequest requestWrapper) {
        // We can get the body directly
        String body = requestWrapper.getBody();
        if(StringUtils.isEmpty(body) || ! JsonUtils.isValidJson(body)) {return requestWrapper;
        }
      
        // Perform other business logic processing on the body, such as parameter reorganization, parameter decryption, etc.
        // The collated public parameters can be stored in RequestAttributes or ThreadLocal for subsequent calls
        // The specific business parameters should be restored to the body, corresponding to the directly parsed parameter object in the Controller
      
        // Put the changed body argument into the wrapper
        requestWrapper.setBody(data);
        returnrequestWrapper; }}Copy the code

Filter registration implementation

There are many implementations of filter registration in SpringBoot. Here are two implementations.

Annotation based implementation

Tag a filter with the @webFilter annotation

/** * <p> * Parameter filter * </p> **@author zhengshangjin
 * @version 1.0.0
 * @since 1.0.0
 * created on 2020-04-03
 */
@Slf4j
@Component
@WebFilter(urlPatterns = "/*", filterName = "serverParamFilter")
public class ServerParamFilter implements Filter {}Copy the code
  • This annotation has multiple parameters, which can be seen in the source code, given hereurlPatternsIntercepts all root request paths, specifiedfilterNameIs the name of the filter.
  • One of the big disadvantages of this approach is that it is impossible to specifyFilterIf multiple filters exist, the @order command cannot be used to specify the priority.
Register your own Bean implementation
/** * <p> * Filter configuration * </p> **@author zhengshangjin
 * @version 1.0.0
 * @since 1.0.0
 * created on 2020-04-03
 */
@Configuration
public class FilterConfiguration {
  
    /** * Create a bean named serverParamFilter */
    @Bean
    public ServerParamFilter serverParamFilter(a) {
        return new ServerParamFilter();
    }

    /**
     * 注册过滤器
     */
    @Bean
    publicFilterRegistrationBean<? > serverParamFilterRegister() { FilterRegistrationBean<? > registration =new FilterRegistrationBean<>(serverParamFilter());
        // Set the intercepting resource path
        registration.addUrlPatterns(Arrays.asList("/ *"));
        // If multiple filters exist, you can use this parameter to specify the order in which the filters are executed
        registration.setOrder(1);
        returnregistration; }}Copy the code
  • Register in this wayFilterAlthough a little more complex than the above method, you can not only customize the interception resource rules, but also implement multipleFilterTo customize the execution sequence.