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.
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.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.