The first step:

To implement permission interception with an annotation, create a custom annotation class:

import java.lang.annotation.*; // @target ({elementType.method}) // @retention (RetentionPolicy.runtime) // @documented Public @interface Role{// Default String value() default"user"; String[] roles() default {}; String[] rolesMust() default {}; }Copy the code

The second step:

Then the custom an interceptor class (inherit HandlerInterceptorAdapter line) :

To keep things simple, I’ll send a userId from the front end to simulate logging in. If it says logged in, it’s not logged in.

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.Method; import java.util.*; /** * Create a custom permission interceptor, Inherited HandlerInterceptorAdapter class * / @ Component / / to spring management public class RoleInterceptor extends HandlerInterceptorAdapter @override public Boolean preHandle(HttpServletRequest Request, HttpServletResponse Response, Object handler) throws Exception { // System.out.println("Passed the RoleInterceptor"); HandlerMethod = (HandlerMethod) handler; Method = handlermethod.getMethod (); // Get the Role annotation on the method Role Role = method.getannotation (role-.class); // If the annotation is null, it does not need to interceptif (role == null) {
            return true; } String userId = (String) request.getParameter(String userId = (String) request.getParameter("userId"); // No message indicating no loginif(userId = = null | | userId. Length () = = 0) {/ / custom login abnormal throw new LoginException (); } // Query the set of roles that users have in the database permission table and compare them to complete the permission verification.if(userRole ! = null && userrole.size ()>0) {// If you have one of the roles, you can passif(role-.roles ().length > 0) {String[] roles = role-.roles (); String[] roles = role-.roles (); // Verify role permissions. Perform this operation by yourself..... // If the role does not pass the check, it can not be processed here, save for the last processing}else if(role-.rolesmust ().length > 0) {// These roles are required to pass String[] rolesMust = role-.rolesmust (); // Verify role permissions. Perform this operation by yourself..... // If the role does not pass the check, it can not be processed here, save for the last processing}else{// Default user String value = role-.value ();for (String str : userRole) {
                    if (value.equals(str)) return true; }}} // Note No custom role exception is thrown. No custom exception can be returned directlyfalseThrow new RoleException(); // Public result should be returned after interception, no processing is done herereturn false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//        System.out.println("postHandler");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//        System.out.println("afterCompletion"); }}Copy the code

Note: The interceptor can only return Boolean values. It cannot return other values. But generally we want simple, clear and friendly information on the front end

Something like this:

{" code ":" OK ", "data" : "success"}Copy the code

Json data like this cannot be returned by the interceptor. So we can customize exceptions so that when we throw an exception, we can return the data we need when we use the global exception class to handle the exception.

Create a custom LoginException:

package com.xoppen.user.exception; import com.xoppen.common.entity.StatusMessage; @author: Xu * @date: 2019/7/9 10:12 */ public class LoginException extends Exception{ public LoginException(Exception e) { super(e); } public LoginException(String msg, Exception e) { super(msg, e); } public LoginException(String msg) { super(msg); } publicLoginException(){ super(StatusMessage.ERROR_LOGIN); }}Copy the code

Create the global exception handler class BaseExceptionHandler:

package com.xoppen.user.exception; import com.xoppen.common.entity.Result; import com.xoppen.common.entity.ResultUtil; import com.xoppen.common.entity.StatusCode; import com.xoppen.common.entity.StatusMessage; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; / / @controllerAdvice public class BaseExceptionHandler {@ExceptionHandler(value = exception.class) @ResponseBody public Result error(Exception e){ e.printStackTrace(); // ResultUtil This is a tool class that returns status codes and prompts. // Handle specific exceptions separately. // Service exceptions are directly reported to usersif(e instanceof LoginException) {// The login is abnormalreturn ResultUtil.error(StatusCode.ERROR_LOGIN, e.getMessage());
        }else if(e instanceof RoleException){// RoleExceptionreturn ResultUtil.error(StatusCode.ERROR_ACCESS, e.getMessage());
        }else if(e instanceof HttpRequestMethodNotSupportedException) {/ / request abnormal wayreturn ResultUtil.error(StatusCode.ERROR, StatusMessage.ERROR_REQUEST);
        }else if(e instanceof DataAccessResourceFailureException) {/ / data source connection timeoutreturn ResultUtil.error(StatusCode.ERROR, StatusMessage.ERROR_DATABASE);
        } else if (e instanceof ErrorException){
            returnResultUtil.error(StatusCode.ERROR, StatusMessage.ERROR); } // Unknown exception returns a unified error messagereturnResultUtil.error( StatusCode.ERROR_SYSTEM, e.getLocalizedMessage()); }}Copy the code

This will return the information we need;

Step 3:

Configuration of the interceptor configuration class (inherit WebMvcConfigurationSupport), make effective interceptor:

import com.xoppen.user.interceptor.JwtInterceptor; import com.xoppen.user.interceptor.RoleInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; / configure interceptors to intercept path * * * * / @ Configuration / / that is a Configuration class public class InterceptorConfig extends WebMvcConfigurationSupport { @Autowired private RoleInterceptor roleInterceptor; Protected void addInterceptors(InterceptorRegistry registry) {// Register interceptors to declare the interceptor object and request to intercept // role interceptors registry.addInterceptor(roleInterceptor) .addPathPatterns("/ * *")
                .excludePathPatterns("/**/login/**"."/**/register/**"); AddInterceptor (roleInterceptor) addPathPatterns(roleInterceptor)"/ * *"ExcludePathPatterns (excludePathPatterns)"/**/login/**"."/**/register/**"Which paths do the interceptor not intercept}}Copy the code

Step 4:

You can annotate the controller method directly:

Like my custom character annotations there are many ways to write, there are many ways to write. It’s all about what you do when you check the character (important)

import org.aspectj.lang.annotation.Aspect; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import java.util.Map; /** * user Controller */ @restController // convert returned data to Json data @crossorigin // resolve cross-domain issues @requestMapping ("/user"Public class UserController {// There are many ways to write a custom role annotation. @role @requestMapping (value =?) @role @requestMapping (value ="/name")
    public Result name1(){
         System.out.println("通过啦!!!!!!"); } @roles (roles = {"user"."admin"})
    @RequestMapping(value = "/name")
    public Result name2(){
         System.out.println("通过啦!!!!!!"); } // @role (rolesMust = {"user"."admin"})
    @RequestMapping(value = "/name")
    public Result name3(){
         System.out.println("通过啦!!!!!!"); } @roles (roles = {"user"."admin"},rolesMust = {"user"."admin"})
    @RequestMapping(value = "/name")
    public Result name4(){
         System.out.println("通过啦!!!!!!"); }}Copy the code

The configuration is complete!!!!!

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — – — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —