注解+动态代理实现权限拦截

动态代理

用于拦截对目标对象的直接访问。代理对象具有自己的方法以及目标对象的全部方法,当被调用的是目标对象的方法时,代理对象先调用自己的方法,再让目标对象调用其对应的方法。

JavaAPI:

Proxy类产生代理对象,调用其静态方法newProxyInstance(ClassLoader,Interfaces[],InvocationHandler(Object proxy,Method method,Object[] args){})。这个静态方法中产生一个InvocationHandler类的内部类对象代表代理对象自己的方法;method代表被调用的方法,args代表方法参数。
条件:目标对象必须实现一个接口
示例代码:

/**
    动态代理解决get方式乱码
**/
public class CharacterEncodingFilter implements Filter{

    public void destroy() {

    }

    public void doFilter(ServletRequest req,ServletResponse resp,FilterChain chain) throws IOException,ServletException {
    final HttpServletRequest request=(HttpServletRequest) req;
    HttpServletResponse response=(HttpServletResponse) resp;

    request.setCharacterEncoding("UTF-8");
    response.setCharacterEncoding("UTF-8");
    response.setContentType("text/html;charset=UTF-8");

/**
    在server.xml文件的8080端口下配置URIEncoding="UTF-8"也可解决get方式中文乱码
*/

    chain.doFilter((ServletRequest)Proxy.newProxyInstance(CharacterEncodingFilter.class.getClassLoader(),request.getClass().getInterfaces(), new InvocationHandler() {
//产生Request的代理对象

    public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
            //拦截getParameter()方法        if(!method.getName().equals("getParameter")){
    return method.invoke(request, args);
}

//post方式无需手动解决乱码,则调用真实对象的方法             if(request.getMethod().equalsIgnoreCase("post")){
    return method.invoke(request, args);
}
//代理对象自己的方法,拦截get方式提交,解决get方式的乱码            
String value=(String) method.invoke(request, args);
    if(value==null){
        return null;
    }
return new String(value.getBytes("ISO8859-1"),"UTF-8");
            }
        }), response);

    }

    public void init(FilterConfig filterConfig) throws ServletException {
    }

}
2 注解+动态代理实现权限拦截

1)产生目标对象的代理对象,在代理对象的自己的方法中实现拦截。

示例:

public class ServiceFactory {

    private static ServiceFactory factory=new ServiceFactory();

    private ServiceFactory(){};

    public static ServiceFactory getInstance(){
        return factory;
    }

    public <T> T getBusinessService(Class<T> clazz,final User user) throws InstantiationException, IllegalAccessException{
        final T t=clazz.newInstance();
    return(T) Proxy.newProxyInstance(ServiceFactory.class.getClassLoader(), clazz.getInterfaces(), new InvocationHandler() {

            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                //获取方法名称
                String name=method.getName();
                System.out.println(name);
                //获取真实对象上的方法
                Method m=t.getClass().getMethod(name, method.getParameterTypes());
                //获取调用的方法上的注解
                Permission p=m.getAnnotation(Permission.class);
                //若注解为空,则无需权限,放行
                if(p==null){
                    return method.invoke(t, args);
                }
                //需要权限,则得到注解内容并new出权限对象
                String value=p.value();
                Privilege pl=new Privilege();
                pl.setName(value);
                //判断用户是否登录,登录则得到用户拥有的权限
                if(user==null){
                    throw new PrivilegeException("对不起,请先登录!");
                }

                BusinessService service=new BusinessService();
                List<Privilege> list=service.findPrivileges(user.getId());


                //判断需要的权限对象用户是否拥有
                if(list.contains(pl)){
                    return method.invoke(t, args);
                }else{
                    throw new PrivilegeException("对不起!您没有权限访问!");
                }

                //没有则抛出权限异常,拥有则放行

            }
        }); 
    }
}

自己写的图书管理系统项目有这样的运用,有兴趣可看看案例源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值