Java注解(Annotation )--結合攔截器實現是否登錄驗證


什么是注解?

  Annotation 中文譯過來就是注解、標釋的意思。現在的技術文檔都是在用專業名詞來介紹專業名詞,理解起來晦澀難懂,我個人認為注解就是用來解釋代碼的。比如@Override注解,就是告訴Java虛擬機我繼承或實現的父類的方法被我重寫了,調用父類該方法時調用我重寫的這個方法。

什么是元注解?

  元注解是可以注解到注解上的注解,或者說元注解是一種基本注解,但是它能夠應用到其它的注解上面。

  如果難於理解的話,你可以這樣理解。元注解也是一張標簽,但是它是一張特殊的標簽,它的作用和目的就是給其他普通的標簽進行解釋說明的。

  元標簽有 @Retention、@Documented、@Target、@Inherited、@Repeatable 5 種。

@Retention

  Retention 的英文意為保留期的意思。當 @Retention 應用到一個注解上的時候,它解釋說明了這個注解的的存活時間。

它的取值如下:

  • RetentionPolicy.SOURCE 注解只在源碼階段保留,在編譯器進行編譯時它將被丟棄忽視。
  • RetentionPolicy.CLASS 注解只被保留到編譯進行的時候,它並不會被加載到 JVM 中。
  • RetentionPolicy.RUNTIME 注解可以保留到程序運行的時候,它會被加載進入到 JVM 中,所以在程序運行時可以獲取到它們。

@Documented

  顧名思義,這個元注解肯定是和文檔有關。它的作用是能夠將注解中的元素包含到 Javadoc 中去。

@Target

  Target 是目標的意思,@Target 指定了注解運用的地方。

  @Target 有下面的取值:

  • ElementType.ANNOTATION_TYPE 可以給一個注解進行注解
  • ElementType.CONSTRUCTOR 可以給構造方法進行注解
  • ElementType.FIELD 可以給屬性進行注解
  • ElementType.LOCAL_VARIABLE 可以給局部變量進行注解
  • ElementType.METHOD 可以給方法進行注解
  • ElementType.PACKAGE 可以給一個包進行注解
  • ElementType.PARAMETER 可以給一個方法內的參數進行注解
  • ElementType.TYPE 可以給一個類型進行注解,比如類、接口、枚舉

@Inherited

  Inherited 是繼承的意思,但是它並不是說注解本身可以繼承,而是說如果一個超類被 @Inherited 注解過的注解進行注解的話,那么如果它的子類沒有被任何注解應用的話,那么這個子類就繼承了超類的注解。 
  說的比較抽象。代碼來解釋。

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface Test {}
@Test
public class A {}
public class B extends A {}

  注解 Test 被 @Inherited 修飾,之后類 A 被 Test 注解,類 B 繼承 A,類 B 也擁有 Test 這個注解。

具體代碼如下:

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;

/**
 * 標注此注解的controller不需要登陸
 * @author 塵世間迷茫的小書童
 *
 */
@Documented //該注解表示 是否被JavaDoc處理並保留在文檔中
@Target({ElementType.METHOD, ElementType.TYPE}) //注解使用的地方
@Retention(RetentionPolicy.RUNTIME) //源碼保留級別
public @interface NoLogin {
	
}
CheckLoginInterceptor:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class CheckLoginInterceptor implements HandlerInterceptor {

	private static final Logger logger = Logger.getLogger(CheckLoginInterceptor.class);
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// TODO Auto-generated method stub
		if(!(handler instanceof HandlerMethod)) {
			logger.warn("當前操作handler不為HandlerMethod=" + handler.getClass().getName() + ",req=" + request.getQueryString());
			return true;
		}
		
		HandlerMethod handlerMethod = (HandlerMethod) handler;
		String methodName = handlerMethod.getMethod().getName();
		NoLogin noLogin = handlerMethod.getMethod().getAnnotation(NoLogin.class);
		if(null != noLogin) {
			logger.info("當前訪問methodName=" + methodName + "不需要登陸");
			System.out.println("當前訪問methodName=" + methodName + "不需要登陸");
			return true;
		}
		
		noLogin = handlerMethod.getMethod().getDeclaringClass().getAnnotation(NoLogin.class);
		if(null != noLogin) {
			logger.info("當前訪問methodName= " + methodName + " 不需要登陸");
			System.out.println("當前訪問methodName= " + methodName + " 不需要登陸");
			return true;
		}
		
		//驗證請求中是否包含session
		if(null == request.getSession()) {
			logger.info("當前訪問 methodName=" + methodName + "用戶未登錄,IP= " + request.getRemoteAddr());
			System.out.println("當前訪問 methodName=" + methodName + "用戶未登錄,IP= " + request.getRemoteAddr());
			return false;
		}
		logger.info("當前訪問methodName=" + methodName + "需要登陸");
		System.out.println("當前訪問methodName=" + methodName + "需要登陸");
		return false;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub

	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub

	}

}
InterceptorConfig:
import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

//也可以繼承WebMvcConfigurerAdapter類只重寫addInterceptors方法,下面代碼比較啰嗦 @Configuration public class InterceptorConfig implements WebMvcConfigurer { @Override public void configurePathMatch(PathMatchConfigurer configurer) { // TODO Auto-generated method stub } @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { // TODO Auto-generated method stub } @Override public void configureAsyncSupport(AsyncSupportConfigurer configurer) { // TODO Auto-generated method stub } @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { // TODO Auto-generated method stub } @Override public void addFormatters(FormatterRegistry registry) { // TODO Auto-generated method stub } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new CheckLoginInterceptor()).addPathPatterns("/**"); } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // TODO Auto-generated method stub } @Override public void addCorsMappings(CorsRegistry registry) { // TODO Auto-generated method stub } @Override public void addViewControllers(ViewControllerRegistry registry) { // TODO Auto-generated method stub } @Override public void configureViewResolvers(ViewResolverRegistry registry) { // TODO Auto-generated method stub } @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { // TODO Auto-generated method stub } @Override public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) { // TODO Auto-generated method stub } @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { // TODO Auto-generated method stub } @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { // TODO Auto-generated method stub } @Override public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) { // TODO Auto-generated method stub } @Override public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) { // TODO Auto-generated method stub } @Override public Validator getValidator() { // TODO Auto-generated method stub return null; } @Override public MessageCodesResolver getMessageCodesResolver() { // TODO Auto-generated method stub return null; } }
TestController:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class TestController {
	
	@NoLogin
	@GetMapping("/user/login.htm")
	@ResponseBody
	public void login(String username, String password) {
		
	}
	
	@ResponseBody
	@GetMapping("/user/userInfo.htm")
	public void getUserInfo(Long userId) {
		
	}
	
	@NoLogin
	@ResponseBody
	@GetMapping("/user/register.htm")
	public void register(String username, String password) {
		
	}
}

  運行效果:

2019-06-29 00:17:41.222  INFO 11388 --- [nio-8001-exec-1] www.mxh.com.CheckLoginInterceptor        : 當前訪問methodName=getUserInfo需要登陸
當前訪問methodName=getUserInfo需要登陸
2019-06-29 00:17:57.987  INFO 11388 --- [nio-8001-exec-4] www.mxh.com.CheckLoginInterceptor        : 當前訪問methodName=login不需要登陸
當前訪問methodName=login不需要登陸
2019-06-29 00:27:37.214  INFO 11388 --- [nio-8001-exec-9] www.mxh.com.CheckLoginInterceptor        : 當前訪問methodName=register不需要登陸
當前訪問methodName=register不需要登陸

  推薦閱讀:https://blog.csdn.net/qq1404510094/article/details/80577555


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM