Backend Development 12 min read

Unified User Login Permission Validation, Exception Handling, and Data Formatting in Spring Boot

This article demonstrates how to implement unified user login permission checks, centralized exception handling, and consistent response formatting in Spring Boot using AOP, HandlerInterceptor, @ControllerAdvice, and ResponseBodyAdvice, providing step‑by‑step code examples and configuration details.

Architecture Digest
Architecture Digest
Architecture Digest
Unified User Login Permission Validation, Exception Handling, and Data Formatting in Spring Boot

The article introduces a comprehensive approach to handling user login validation, exception handling, and response formatting in a Spring Boot application.

1. Unified User Login Permission Validation

Four versions of login validation are discussed, culminating in the use of Spring AOP and HandlerInterceptor to centralize the logic.

1.1 Initial Validation

@RestController
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/a1")
    public Boolean login(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session != null && session.getAttribute("userinfo") != null) {
            return true;
        } else {
            return false;
        }
    }
    @RequestMapping("/a2")
    public Boolean login2(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session != null && session.getAttribute("userinfo") != null) {
            return true;
        } else {
            return false;
        }
    }
}

This approach repeats the same validation code in each controller method, leading to maintenance issues.

1.2 Spring AOP Validation

@Aspect
@Component
public class UserAspect {
    @Pointcut("execution(* com.example.springaop.controller..*.*(..))")
    public void pointcut() {}

    @Before("pointcut()")
    public void doBefore() {}

    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        System.out.println("Around method start");
        Object obj = null;
        try {
            obj = joinPoint.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("Around method end");
        return obj;
    }
}

AOP can centralize validation but cannot directly access HttpSession and may have complex pointcut requirements.

1.3 Spring Interceptor

@Component
public class LoginIntercept implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession(false);
        if (session != null && session.getAttribute("userinfo") != null) {
            return true;
        }
        response.sendRedirect("/login.html");
        return false;
    }
}

@Configuration
public class AppConfig implements WebMvcConfigurer {
    @Resource
    private LoginIntercept loginIntercept;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginIntercept)
                .addPathPatterns("/**")
                .excludePathPatterns("/user/login", "/user/reg", "/login.html", "/reg.html", "/**/*.js", "/**/*.css", "/**/*.png", "/**/*.jpg");
    }
}

The interceptor checks the session before each request and redirects unauthenticated users to the login page, with configurable inclusion and exclusion patterns.

1.4 Practice Exercise

Implement login and index pages, ensuring that login/registration URLs are excluded from interception while other pages require a valid session.

2. Unified Exception Handling

@RestControllerAdvice
public class MyExceptionAdvice {
    @ExceptionHandler(ArithmeticException.class)
    public HashMap
arithmeticExceptionAdvice(ArithmeticException e) {
        HashMap
result = new HashMap<>();
        result.put("state", -1);
        result.put("data", null);
        result.put("msg", "Arithmetic exception: " + e.getMessage());
        return result;
    }

    @ExceptionHandler(NullPointerException.class)
    public HashMap
nullPointerExceptionAdvice(NullPointerException e) {
        HashMap
result = new HashMap<>();
        result.put("state", -1);
        result.put("data", null);
        result.put("msg", "Null pointer exception: " + e.getMessage());
        return result;
    }

    @ExceptionHandler(Exception.class)
    public HashMap
exceptionAdvice(Exception e) {
        HashMap
result = new HashMap<>();
        result.put("state", -1);
        result.put("data", null);
        result.put("msg", "Exception: " + e.getMessage());
        return result;
    }
}

The advice class captures specific exceptions first, then falls back to a generic handler, ensuring consistent error responses.

3. Unified Data Format Return

@ControllerAdvice
public class MyResponseAdvice implements ResponseBodyAdvice
{
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        HashMap
result = new HashMap<>();
        result.put("state", 1);
        result.put("data", body);
        result.put("msg", "");
        return result;
    }
}

@RestController
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/login")
    public boolean login(HttpServletRequest request, String username, String password) {
        if (StringUtils.hasLength(username) && StringUtils.hasLength(password) && "admin".equals(username) && "admin".equals(password)) {
            HttpSession session = request.getSession();
            session.setAttribute("userinfo", "userinfo");
            return true;
        }
        return false;
    }

    @RequestMapping("/reg")
    public int reg() {
        return 1;
    }
}

By implementing ResponseBodyAdvice , all controller responses are wrapped in a uniform JSON structure containing a status code, data payload, and message.

Overall, the article provides a step‑by‑step guide to consolidating authentication, error handling, and response formatting in Spring Boot, improving code maintainability and consistency across the application.

AOPbackend developmentException HandlingSpring BootInterceptorResponseBodyAdvice
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.