讨论区交流平台项目 - 检查登录状态

功能分析

目前我们开发的所有的功能都有着对应的接口路径,虽然我们没有登录前看不到一些功能入口,但是如果我们知道对应的功能路径,我们也是直接输入路径就可以访问。
所以我们需要验证用户的登录状态,当用户没有登录的时候,在访问这些没有权限的功能的是我们应该在服务端拒绝访问。
很明显这个检查登录状态会是很多功能点共有的一段逻辑,那么根据之前的开发,很容易就想到用拦截器进行实现,而这里我们使用自定义注解 + 拦截器的形式来解决这种问题。
拦截器拦截所有的请求,但是只处理带有该注解的方法。
我们想自定义解决的话是需要借助元注解要实现,常用的元注解有:
@Target、@Retention、@Document、@Inherited
分别代表我自定义的注解可以写在哪个位置,可以作用在哪个类型上;自定义注解有效的时间;自定义注解在生成文档的时候带不带上它;自定义注解是否继承。

开发步骤

自定义注解

我们根据需要自定义注解,而目前我们需要检查登录状态才能访问的功能路径有 setting,upload 这两个上面。
LoginRequired 注解:

package com.spring.community2.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
// 注解用来描述方法
@Target(ElementType.METHOD)
// 注解有效的时长:运行时有效
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginRequired {
}

在需要检查的方法上面增加对应的自定义注解。
UserController 类:

@LoginRequired
@RequestMapping(path = "/setting", method = RequestMethod.GET)
public String getSettingPage() {
    return "/site/setting";
}
@LoginRequired
@RequestMapping(path = "/upload", method = RequestMethod.POST)
public String uploadHeader(MultipartFile headerImage, Model model) {
    if (headerImage == null) {
        model.addAttribute("error", "你还没有上传图片");
        return "/site/setting";
    }
    String fileName = headerImage.getOriginalFilename();
    String suffix = fileName.substring(fileName.lastIndexOf('.'));
    if (StringUtils.isBlank(suffix)) {
        model.addAttribute("error", "文件的格式不正确");
        return "/site/setting";
    }
    // 生成随机的文件名
    fileName = CommunityUtil.generateUUID() + suffix;
    // 确定文件存放的位置
    File dest = new File(uploadPath + "/" +fileName);
    try {
        // 存储文件
        headerImage.transferTo(dest);
    } catch (IOException e) {
        logger.error("上传文件失败:" + e.getMessage());
        throw new RuntimeException("上传文件失败,服务器发生异常" + e);
    }
    // 更新当前用户头像的路径(web路径)
    // http://localhost:8080/community/user/header/***.png
    User user = hostHolder.getUser();
    String headerUrl = domain + contextPath + "/user/header/" + fileName;
    userService.updateHeader(user.getId(), headerUrl);
    return "redirect:/index";
}

开发拦截器

我们利用拦截器拦截带有注解的方法,在拦截到之后判断是否登录。
LoginRequiredInterceptor 拦截器:

package com.spring.community2.controller.interceptor;
import com.spring.community2.annotation.LoginRequired;
import com.spring.community2.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
/**
 * @ClassName LoginRequiredInterceptor
 * @Author ruizhou
 * @Date 2020/5/23 21:20
 **/
@Component
public class LoginRequiredInterceptor implements HandlerInterceptor {
    @Autowired
    HostHolder hostHolder;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 只拦截方法
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            LoginRequired loginRequired = method.getAnnotation(LoginRequired.class);
            if (loginRequired != null && hostHolder.getUser() == null) {
                response.sendRedirect(request.getContextPath() + "/login");
                return false;
            }
        }
        return true;
    }
}

拦截器注册

定义好了拦截器,当然要进行拦截器的注册并进行对应的配置。

package com.spring.community2.config;
import com.spring.community2.controller.interceptor.LoginRequiredInterceptor;
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.WebMvcConfigurer;
/**
 * @ClassName WebMvcConfig
 * @Author ruizhou
 * @Date 2020/5/22 21:55
 **/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Autowired
    private LoginRequiredInterceptor loginRequiredInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginRequiredInterceptor)
                .excludePathPatterns("/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg");
    }
}

实现效果

输入 setting 功能路径,会自动跳转登录页面,这里为了展示我没有点回车,实际路径已经是 login。在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值