美文网首页
路径参数处理特殊字符&自定义参数注解处理器

路径参数处理特殊字符&自定义参数注解处理器

作者: GoddyWu | 来源:发表于2018-04-17 17:26 被阅读0次

公司大佬说,restful API 的规范写法是通过路径参数(path variable)的方式获取请求参数。 但是常见一个问题,有些uid中包含特殊字符,例如:\, #, ,以及空格等等。所以采用base64加密解密的方式。
所以后端需要encode uid去掉特殊字符后签发给前端,前端传输到后端后decode uid获取原始uid。
因为前端需要频繁发送uid给后端,用工具方法来解析需要维护大量的代码,所以博主想到了通过自定义参数注解的方式。
⚠️注意:base64不支持中文。

代码地址:https://gitlab.com/goddy-basic/basic_annotation

Part 1 : 环境

  • spring boot 2.0 +
  • pom 包依赖
     <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--小插件、非必要-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--切面-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <!--小插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.10</version>
        </dependency>
    </dependencies>

Part 2 : base64工具类的创建

public class Base64Util {

    /**
     * 二进制数据编码为BASE64字符串
     * @param str 输入数据
     * @return
     */
    public static String encode(final String str) {
        try {
            return new String(Base64.encodeBase64(str.getBytes("UTF-8")), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 解密
     * @param str
     * @return
     */
    public static String decode(final String str) {
        try {
            return new String(Base64.decodeBase64(str.getBytes("UTF-8")), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }
}

Part 3 : 注解声明 create annotation

@Target({ElementType.PARAMETER})  #作用范围
@Retention(RetentionPolicy.RUNTIME)  #生效时期
@Documented  #文档化
public @interface DecodeAnnotation {

}

Part 4 : 配置注解处理器 create annotation resolver

@Slf4j  #非必要、lombok插件的注解
@Component  
public class DecodeResolver implements HandlerMethodArgumentResolver {

    /**
     * 用于判定是否需要处理该参数分解,返回true为需要,并会去调用下面的方法resolveArgument。
     * @param parameter
     * @return
     */
    @Override
    public boolean supportsParameter(MethodParameter parameter) {

        return parameter.hasParameterAnnotation(DecodeAnnotation.class);
    }

    /**
     * 真正用于处理参数分解的方法,返回的Object就是controller方法上的形参对象。
     * @param parameter
     * @param mavContainer
     * @param webRequest
     * @param binderFactory
     * @return
     * @throws Exception
     */
    @Nullable
    @Override
    public Object resolveArgument(MethodParameter parameter,
                                  @Nullable ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest,
                                  @Nullable WebDataBinderFactory binderFactory) throws Exception {

        @SuppressWarnings("unchecked")
        Map<String, String> uriTemplateVars =
                (Map<String, String>) webRequest.getAttribute(
                        HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);

        LinkedHashMap hashMap = new LinkedHashMap<>(uriTemplateVars);

        # 获取到注解的值
        String value = hashMap.get( parameter.getParameterName() ).toString();

        return Base64Util.decode(value);
    }
}

Part 5 : 注册注解处理器 register resolver

@Configuration
public class WebMvcConfiguration extends WebMvcConfigurationSupport {

    @Override
    protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {

        super.addArgumentResolvers(argumentResolvers);

        //注册decode的参数处理器
        argumentResolvers.add(new DecodeResolver());
    }
}

Part 6 : 验证

  • 通过Basic6Util的encode方法加密一段uid
    • 例如:wcm, a beautiful girl. r\ig/ht? =>
      d2NtLCBhIGJlYXV0aWZ1bCBnaXJsLiByXGlnL2h0PyA=
  • 测试controller
  • 解密结果

酷不酷、?

参考资料

相关文章

网友评论

      本文标题:路径参数处理特殊字符&自定义参数注解处理器

      本文链接:https://www.haomeiwen.com/subject/lykpkftx.html