• Daily Archives: 2020年4月22日

Spring自定义注解(parameter)

1、新建注解接口VerifyAccount.java:

package com.zero4j.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented

public @interface VerifyAccount {

	String paramName() default "token";
	
	String permission() default "";
}

2、创建注解对应的切面类VerifyAccountAspect.java:

package com.zero4j.annotation;

import net.sf.json.JSONObject;

import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.multipart.support.MissingServletRequestPartException;

import com.zero4j.model.account.Account;
import com.zero4j.model.token.util.TokenStaticUtil;

@Aspect
@Component
public class VerifyAccountAspect implements HandlerMethodArgumentResolver{

	@Override
	public boolean supportsParameter(MethodParameter parameter) {
		return parameter.hasParameterAnnotation(VerifyAccount.class);
	}

	@Override
	public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
		
		String token = webRequest.getParameter("token");
		
		 JSONObject out = new JSONObject();
		
		if(token==null||token.equals("")){
			out.put("status", 401);
			out.put("message", "请先注册并登录后再进行此操作");
			out.put("debug", "缺少参数token或为空");
			//ResponseStaticUtil.write(response,out);
			System.out.println(out.toString());
			//return;
		}
		Account account = TokenStaticUtil.getAccount(token);
		if(account==null){
			out.put("status", 401);
			out.put("message", "请先注册并登录后再进行此操作");
			out.put("debug", "token对应的account为空");
			//ResponseStaticUtil.write(response,out);
			System.out.println(out.toString());
			throw new MissingServletRequestPartException("account");
			//return;
		}
		
		return account;
	}
	
}

注意要实现接口:HandlerMethodArgumentResolver

3、最后要在SpringMVC的配置java类中加入对应的代码:

package com.zero4j.config;

import java.util.List;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.zero4j.annotation.VerifyAccountAspect;

@Configuration
public class WebAppConfigurer implements WebMvcConfigurer {


	@Override
	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
		
		resolvers.add(new VerifyAccountAspect());
		
		WebMvcConfigurer.super.addArgumentResolvers(resolvers);
	}

}

注意这行:resolvers.add(new VerifyAccountAspect());

Spring自定义注解(method)

先定义一个注解接口 VerifyToken.java :

package com.zero4j.annotation;

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented

public @interface VerifyToken {

	//权限参数
	String permission() default "";
	
}

再在同目录中定义一个切面类VerifyTokenAspect.java:

package com.zero4j.annotation;

import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.zero4j.model.account.Account;
import com.zero4j.model.permission.util.PermissionStaticUtil;
import com.zero4j.model.token.util.TokenStaticUtil;
import com.zero4j.util.ResponseStaticUtil;

@Aspect
@Component
public class VerifyTokenAspect {

	@Pointcut("@annotation(com.zero4j.annotation.VerifyToken)")	//这是annotation对应类的所在位置,若目录不同,则填写完整路径,如:com.zero4j.annotation.VerifyToken
    private void pointcut(){
		
	}
	
	@Around("pointcut()&&@annotation(verifyToken)")
	public void around(ProceedingJoinPoint pjp, VerifyToken verifyToken) throws Throwable{
		
		//System.out.println("annotation执行前");
		
		//System.out.println("verifyToken.permission() = "+verifyToken.permission());
		
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        HttpServletResponse response = attributes.getResponse();
        
        String token = request.getParameter("token");
        
        JSONObject out = new JSONObject();
		
		if(token==null||token.equals("")){
			out.put("status", 401);
			out.put("message", "请先注册并登录后再进行此操作");
			out.put("debug", "缺少参数token或为空");
			ResponseStaticUtil.write(response,out);
			//System.out.println(out.toString());
			return;
		}
		Account account = TokenStaticUtil.getAccount(token);
		if(account==null){
			out.put("status", 401);
			out.put("message", "请先注册并登录后再进行此操作");
			out.put("debug", "token对应的account为空");
			ResponseStaticUtil.write(response,out);
			//System.out.println(out.toString());
			return;
		}
		
		if(!(verifyToken.permission()==null||verifyToken.permission().equals(""))){
			if(PermissionStaticUtil.verify(account.getId(), verifyToken.permission())==false){
				out.put("status", 403);
				out.put("message", "你无权进行本操作");
				out.put("debug", "你没有"+verifyToken.permission()+"权限");
				ResponseStaticUtil.write(response,out);
				//System.out.println(out.toString());
				return;
			}
		}
		
		if(out.size()==0){
			pjp.proceed();
		}

	}

}

最后在需要切入的地方加上注解即可:

	@VerifyToken(permission="adminLog_read")
	@RequestMapping(value="", method=RequestMethod.GET)
	public void list(HttpServletRequest request, HttpServletResponse response,
			@RequestParam(required=false) String token,
			@RequestParam(required=false) Integer offset,
			@RequestParam(required=false) Integer limit,
			@RequestParam(required=false) String startTime,
			@RequestParam(required=false) String endTime,
			@RequestParam(required=false) String accountNickname,
			@RequestParam(required=false) String accountMobile,
			@RequestParam(required=false) String description
		){
		
		........

		}

 

close