访问链接:http://localhost:8080/xxxx
由于xxxx接口没有被定义过,界面会返回404
这里我做的处理是,如果用户身份标识为空或无效那么我会默认跳转到登录页。
测试方法是打开一个无痕界面,随便输入一个链接:http://localhost:8080/user/query
由于Cookie中token不存在,所以我不管访问的是哪个链接,直接将状态码改为401,而CustomErrorController遇到401的错误,会默认重定向到登录页。
Filter异常的全局处理除了ErrorController之外,还可以通过自定义拦截器的方式实现,这两个东西会一个就行了。这里我再说一个高级一点的东西,举个例子:
我在一个无痕窗口调用接口:http://localhost:8080/user/query?userName=小B
因为当前窗口的Cookie中是没有token的,按照401错误的处理方式,我会重定向到登录页去。
但这个有一个问题:重新登录之后,进入的是首页,不是调用user/query接口,我还得重新去找这个接口,重新输入参数。而且这要是一个分享页那就尴尬了,登陆完不知道对方分享了啥,用户体验会很差,那么有办法优化这个问题吗?答案是有,如何做,继续看。
所谓全路径就是“http://localhost:8080/user/query?userName=小B” ,如何获取,可以用我这个方法
/**
* 获取完整的路径URL,包括参数
*
* @param httpServletRequest
* @return 路径URL
*/
private String getRequestURL(HttpServletRequest httpServletRequest) {
String url = httpServletRequest.getRequestURL().toString();
String query = httpServletRequest.getQueryString();
if (query != null) {
url = "?" query;
}
return url;
}
2. 在WebFilter抛出401错误的地方设置httpServletResponse的header
如下
httpServletResponse.setHeader("redirectURL",URLEncoder.encode(getRequestURL(httpServletRequest), "utf-8"));
因为参数有可能是中文,这里需要用URLEncoder转下义。
3. 在CustomErrorController中获取到这个跳转链接// 重定向到登录页或指定页面
if (StringUtils.isNotBlank(response.getHeader("redirectURL"))) {
return new ModelAndView("redirect:/login?redirectURL=" response.getHeader("redirectURL"));
}
效果如下
可以看到我们在login后面携带了一个redirectURL参数
4. 登录提交时将redirectURL参数一并提交 @PostMapping("/login")
public void userLogin(@RequestParam(required = true) String userName,
@RequestParam(required = true) String password,
@RequestParam(required = false) String redirectURL,
HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) {
userService.login(userName, password, redirectURL, httpServletRequest, httpServletResponse);
}
5. 验证通过后重定向到redirectURL
try {
//如果跳转路径不为空,则直接重定向到跳转路径
if (StringUtils.isNotBlank(redirectURL)) {
httpServletResponse.sendRedirect(redirectURL);
return;
}
//跳转到登录页
httpServletResponse.sendRedirect("/index");
} catch (IOException e) {
log.error("重定向发生异常", e);
}
,