Springboot通过自定义注解绑定Filter与Handler
- 简介
-
- 使用步骤(示例)
-
- 定义名称注解@Authorization
- 定义 Filter实现用户权限认证
- 为资源开启用户认证
- 测试
- 源码
- 下载
简介
利用Jersey框架开发Restful Web服务时,对于过滤器组件, Jersey提供名称绑定的方式,我们可以灵活的配置过滤器。通过在过滤器和资源上添加同样的自定义名称注解,来绑定过滤器和特定资源,方便直观。
在Springboot中,只能在注册过滤器时指定需要过滤或者不需要过滤的请求地址的方式来过滤特定资源,或者在过滤器的实现中通过硬编码的方式实现更复杂的过滤规则,例如过滤POST请求,放行GET请求等。但是这种方式不够直观,更新过滤规则需要修改代码,也很不方便。
本文主要是在Springboot中提供实现类似的名称绑定方案。类名称大都沿用javax.ws.rs中相同的名称,实现的不够全面,而且只提供请求过滤的实现,但是基本可以满足大多数应用场合。使用者也可以自行进行修改完善。文末提供源码下载链接,同时提供了具体的应用项目示例。
使用步骤(示例)
定义名称注解@Authorization
使用Java标准的注解定义方式,定义一个运行时的、可以作用于方法和类上的注解。
@NameBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Authorization {
}
定义 Filter实现用户权限认证
通过实现接口ContainerRequestFilter实现@Authorization注解的具体功能。
- 在Springboot框架中注册为Bean实例@Component;
- 绑定名称注解@Authorization
@Component
@Authorization
public class LoginFilter implements ContainerRequestFilter
{
protected static String TOKEN ="123456"; //only for test
@Override
public boolean filter(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException
{
// TODO Auto-generated method stub
System.out.println("LoginFilter in!!!!!");
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse rsp = (HttpServletResponse) servletResponse;
rsp.setCharacterEncoding("UTF-8");
rsp.setContentType("application/json; charset=utf-8");
String token = req.getParameter("token");//attach token with query parameter
GeneralWebRsp gRsp=new GeneralWebRsp();
gRsp.setCode(4000);
gRsp.setMessage("认证失败");
if(token!=null)
{
if(TOKEN.equals(token))
{
gRsp.setCode(200);
gRsp.setMessage("认证通过");
}
}
if (gRsp.getCode() !=200)
{// 验证失败
PrintWriter writer = null;
OutputStreamWriter osw = null;
osw = new OutputStreamWriter(servletResponse.getOutputStream(),
"UTF-8");
writer = new PrintWriter(osw, true);
ObjectMapper objectMapper = new ObjectMapper();
String jsonStr = objectMapper.writeValueAsString(gRsp);
writer.write(jsonStr);
writer.flush();
writer.close();
osw.close();
return false;
}
return true;
}
}
-
filter返回值
true :通过过滤条件,将进入后续的过滤器链
false :未通过过滤条件,返回响应,将中断后续的过滤器链
为资源开启用户认证
为资源对应的Controller或者具体的处理方法添加注解@Authorization。
@RequestMapping(value="/openapi/getUserList",method=RequestMethod.GET)
@ResponseBody
@Authorization //In such case name-bound filters bound by @Authorization
//will be applied to this handler method
public GeneralWebRsp<List<User>> getUserList()
{
GeneralWebRsp<List<User>> grsp=new GeneralWebRsp<>();
List<User> users=new ArrayList<>();
User user= new User();
user.setAge(8);
user.setSex("男");
user.setName("王二小");
users.add(user);
user= new User();
user.setAge(16);
user.setSex("女");
user.setName("刘胡兰");
users.add(user);
grsp.setCode(200);
grsp.setMessage("操作成功");
grsp.setData(users);
return grsp;
}
注:也可以将@Authorization作用于Controller,这样可以为Controller中的所有方法开启用户认证过滤。
测试
- 在浏览器中直接访问http://localhost:8080/openapi/getUserList,返回
{"code":4000,"message":"认证失败","data":null}
- 在浏览器中直接访问http://localhost:8080/openapi/getUserList?token=123456,返回
{"code":200,"message":"操作成功","data":[{"name":"王二小","sex":"男","age":8},{"name":"刘胡兰","sex":"女","age":16}]}