公司大佬说,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
- 解密结果
酷不酷、?
网友评论