Spring MVC 提供 HandlerInterceptor 介面,三大切點:
preHandle:Controller 執行前,回傳 true 放行,false 截斷postHandle:Controller 執行後、視圖渲染前afterCompletion:視圖渲染後實務上繼承 HandlerInterceptorAdapter 僅覆寫所需方法。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface AuthPassport {
boolean validate() default true; // false 表示跳過驗證
}
public class AuthInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod hm = (HandlerMethod) handler;
AuthPassport auth = hm.getMethodAnnotation(AuthPassport.class);
if (auth == null || !auth.validate()) return true; // 無註解或標註跳過
// 此處實作實際權限邏輯,例如檢查 Session/Token
boolean hasPermission = checkPermission(request); // 自行實作
if (hasPermission) return true;
// 驗證失敗:重導向登入頁
response.sendRedirect(request.getContextPath() + "/account/login");
return false;
}
return true;
}
}
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
<bean class="com.demo.web.auth.AuthInterceptor"/>
</mvc:interceptors>
@Controller
@RequestMapping("/helloworld")
public class HelloWorldController {
@AuthPassport
@RequestMapping({"/index", "/hello"})
public ModelAndView index() {
ModelAndView mv = new ModelAndView("index");
mv.addObject("message", "Hello World!");
return mv;
}
}
未登入訪問受保護頁面 → 自動跳轉 /account/login;登入後正常顯示。註解式聲明讓權限控制清晰可維護。