开发在线法律咨询平台的设计与实现Day2

今日完成

登录接口

UserController.java

  /**
     * 用户登录接口
     * @param userAccount 用户账号
     * @param userPassword 用户密码
     * @return 返回脱敏后的用户数据
     */
    @PostMapping("/login")
    public BaseResponse<String> userLogin(String userAccount,String userPassword ){

        if(StringUtils.isAnyBlank(userAccount,userPassword)){
            throw new BusinessException(ErrorCode.NULL_ERROR);
        }

        String token = userService.userLogin(userAccount, userPassword);
        return ResultUtils.success(token);
    };

UserServiceImpl.java

//登录业务层
@Override
    public String userLogin(String userAccount, String userPassword) {
        //验证是否非空,不为空执行下一步
        if (StringUtils.isAnyBlank(userAccount,userPassword)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"账号密码为空");
            //账号不能小于4位
        }
        if (userAccount.length()<4){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"账号不能小于4位");
        }
        //密码不能小于8位
        if (userPassword.length()<8 ){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"密码不能小于8位");
        }
        //账户不包含特殊字符
        String regEx="[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*() ——+|{}【】‘;:”“’。,、?]";
        Matcher matcher = Pattern.compile(regEx).matcher(userAccount);
        if (matcher.find()){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"账号包含特殊字符");
        }
        //加密
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
        //查询用户是否存在
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("userAccount",userAccount);
        qw.eq("userPassword",encryptPassword);
        User user = userMapper.selectOne(qw);
        //用户不存在
        if(user ==null){
            log.info(" user login failed, userAccount cannot match userPassword");
            throw new BusinessException(ErrorCode.FAIL_SEARCH,"账号或密码错误");
        }
        Map<String, Object> claims = new HashMap();
        claims.put("id",user.getId());
        claims.put("username",user.getUsername());

        String token = JwtUtil.genToken(claims);
        getSafetyUser(user);//脱敏
        return token;
    }
	//用户脱敏
	@Override
    public User getSafetyUser(User originUser){
        if(originUser == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"脱敏失败");
        }
        User safetyUser = new User();
        safetyUser.setId(originUser.getId());
        safetyUser.setUsername(originUser.getUsername());
        safetyUser.setUserAccount(originUser.getUserAccount());
        safetyUser.setAvatarUrl(originUser.getAvatarUrl());
        safetyUser.setUserRole(originUser.getUserRole());
        safetyUser.setGender(originUser.getGender());
        safetyUser.setPhone(originUser.getPhone());
        safetyUser.setEmail(originUser.getEmail());
        safetyUser.setUserStatus(originUser.getUserStatus());
        safetyUser.setCreateTime(originUser.getCreateTime());
        return safetyUser;
    }

整合jwt

导入依赖

        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>4.4.0</version>
        </dependency>

jwt工具类
JwtUtil.java

public class JwtUtil {
    //接受业务数据,生成token并返回
    public static String genToken(Map<String, Object> claims){
        return JWT.create()
                .withClaim("claims",claims)
                .withExpiresAt(new Date(System.currentTimeMillis() + 1000*60*60*24))
                .sign(Algorithm.HMAC256(UserContant.SALT));
    }
    //接受token,验证token是否有效
    public static Map<String,Object> parseToken(String token){
        return JWT.require(Algorithm.HMAC256(UserContant.SALT))
                .build()
                .verify(token)
                .getClaim("claims")
                .asMap();
    }
}

拦截器
LoginInterceptor.java

@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("Authorization");
        try{
            // 解析token
            Map<String,Object> claims = JwtUtil.parseToken(token);
            ThreadLoaclUtil.set(claims);
            return true;
        }catch (Exception e){
            response.setStatus(401);
            return false;
        }
    }
    // 请求处理完毕移THREAD_LOCAL中除线程变量
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        ThreadLoaclUtil.remove();
    }
}

配置拦截器
WebConfig.java

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Resource
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //登录接口和注册接口不需要拦截
        registry.addInterceptor(loginInterceptor).excludePathPatterns("/user/login","user/register");
    }
}

开发中遇到的问题

一、无法获取对象

问题描述: 程序可以从数据库中拿到数据,却无法存在对象中。

解决过程: 配置map-underscore-to-camel-case: true
具体实现:

mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true #下划线命名法自动映射为驼峰命名法的功能。解决了数据库中表字段名与实体类属性名不一致的问题。

二、获取用户信息过于繁琐

问题描述: 每次请求访问时,要想拿到token中存取的数据,都要在每个方法中以参数的形式获取请求头中的Authorization,在解析token,太过繁琐。

解决过程: 由于在请求拦截时每次都会获取一次Authorization并解析token,我们只需要引入ThreadLocal来提供线程局部变量,在请求拦截时把解析后的token存储在ThreadLocal线程中,然后在每个请求方法下使用ThreadLocal.get()方法就可以拿到。
具体实现:
封装一个工具类

public class ThreadLoaclUtil {
    private static final ThreadLocal THREAD_LOCAL = new ThreadLocal();

    // 获取线程变量
    public static <T> T get() {
        return (T)THREAD_LOCAL.get();
    }
    // 设置线程变量
    public static void set(Object value) {
        THREAD_LOCAL.set(value);
    }
    // 移除线程变量
    public static void remove() {
        THREAD_LOCAL.remove();
    }
}

请求拦截前

ThreadLoaclUtil.set(claims);

一次响应结束后

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        ThreadLoaclUtil.remove();
    }

需要token解析参数时

Map<String,Object> map = ThreadLoaclUtil.get();

小组会议(设计系统)

在线法律咨询平台的设计与实现

设计

  1. √ 用户注册与登录:用户可以注册个人账号,并通过登录方式访问平台。

  2. √提问咨询:用户可以提出法律问题,并描述详细情况,以便律师准确理解问题。
    image

image

  1. √律师匹配:系统可以根据用户的问题需求,自动匹配或推荐合适的专业律师进行解答。

  2. √在线交流:用户和律师之间可以通过文字、语音或视频等方式进行实时在线交流,解答疑问。

image

  1. √文件上传:用户可以上传相关法律文件或证据,以便律师更好地了解问题情况并提供解决方案。

  2. √支付结算:平台支持用户支付法律咨询费用的功能,平台进行结算并支付给律师。

image

  1. √线上咨询记录:系统将记录用户与律师之间的交流内容和咨询记录,方便双方查阅。

image

  1. 用户评价与反馈:用户可以对咨询服务的质量和效果进行评价,并留下反馈意见。

  2. 法律知识库:平台可能提供法律知识库,包括法律条文、案例分析等内容,方便用户查询。

  3. 用户管理:系统可以管理用户信息、订单记录,保护用户隐私和数据安全。

登录——>描述问题——>系统列出匹配律师——>支付页面——>在线交流

技术栈

posted @ 2024-09-24 22:54  尤所不同  阅读(18)  评论(0编辑  收藏  举报