用户登陆和用户认证的编写的方式

这篇博客详细介绍了使用Java进行用户登录和认证的实现过程,包括导入相关包、编写登录Servlet、设计结果集封装接口和枚举、创建返回对象、定义Java实体类、处理业务异常、实现JDBC工具类、封装请求参数工具类以及生成token的工具类等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1.1、导入咋们的包

1.2、编写登陆的Servlet

1.3、编写结果集封装的这样一个接口

1.5、编写结果集封装的返回对象

1.6、编写Java的实体类

1.7、编写业务异常

1.8、编写JDBC的工具类

1.9、编写请求参数封装的这样一个工具类

1.10、编写token生成的工具类


1.1、导入咋们的包

  <!--导包-->
​
        <!--
            <scope>provided</scope>: provided:这一句话表示的意思是 我们的Tomcat中已经存在这个包了 这个项目在
            运行打包的时候这个包呢就不需要打了
        -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
​
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>
​
        <dependency>
            <groupId>org.apache.taglibs</groupId>
            <artifactId>taglibs-standard-impl</artifactId>
            <version>1.2.5</version>
        </dependency>
​
​
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.3</version>
        </dependency>
​
​
        <!--动态生成getter和setter方法的  全参无参构造器的  toString
        在使用的时候
        @Data
        @Allxxxx
        @Noxxxx
        -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
            <scope>provided</scope>
        </dependency>
​
​
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
​
​
        <!--导入数据库的驱动
       简单的说就是JDBC的实现类
   -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.40</version>
        </dependency>
​
​
        <!--这个是Druid的包-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
​
​
        <!--下面导入dbutils这个包-->
        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>1.6</version>
        </dependency>
​
​
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.54</version>
        </dependency>

1.2、编写登陆的Servlet

@WebServlet(urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }
​
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
        /**
         * 登陆的逻辑
         *   1、接受前端传过来的用户名和密码
         *   2、通过用户名查询用户对象(去数据库进行查询)
         *   3、没有找到 :说明用户名有误
         *   4、找到了 那么比较密码是否一致
         *      密码不一致 那么说明 密码有误
         *      密码一致 那么说明用户身份合法
         *   5、用户身份合法 那么生成唯一的标识 token(实际上就是一个字符串)
         *   6、将用户身份唯一的标识 存储到数据库 中
         *   7、将身份唯一的标识 和用户数据非密码传输到 前端页面进行保存
         *   8、前端在请求资源的时候 只需要带上令牌token就可以请求资源
         */
        try {
            //第一步:解决编码问题
            req.setCharacterEncoding("UTF-8");
            //第二步:获取前端传递过来的数据
            User user = ObjectUtils.getInstance().getParameterObject(req, User.class);
            if(null==user || StringUtils.isEmpty(user.getUserName()) || StringUtils.isEmpty(user.getPassword())){
                //这里的需错误的状态吗  和 错误的信息 是不能直接在这里写死的
                //你先过一个问题没有 如果是我们的状态码后来觉得 需要修改 那不是你还要改源码? 是不利于你维护这个错误信息
                 throw new BusinessException(ResponceCode.PARAMETER_ERROR.getCode(),ResponceCode.PARAMETER_ERROR.getMessage());
            }
            //第三步:通过用户名去查询用户对象
            User queryUser = JdbcUtils.queryRunner().query("select * from t_user where userName=?", new BeanHandler<User>(User.class), user.getUserName());
            if(null==queryUser){
                 throw new BusinessException(ResponceCode.USERNAME_ERROR.getCode(),ResponceCode.USERNAME_ERROR.getMessage());
            }
            //执行到这里 说明咋们的用户名是对的 那么比较密码是否一致
            if(!StringUtils.equals(user.getPassword(),queryUser.getPassword())){
               throw new BusinessException(ResponceCode.PASSWORD_ERROR.getCode(),ResponceCode.PASSWORD_ERROR.getMessage());
            }
            //执行到这里 说明密码是对的
            //生成token  这个token就是用户身份唯一的标识 只要唯一就可以了
            String token = TokenUtils.getToken();
            //将这个信息 更新到数据库中(目前我们用的是数据库)
            JdbcUtils.queryRunner().update("update t_user set token=? where userName=?",token,user.getUserName());
            //执行到这里说明更新完成
            //首先将密码信息置空
            queryUser.setPassword("");
            //将token信息设置到用户对象
            queryUser.setToken(token);
​
            //封装返回的对象
            DataResult<User> userDataResult = new DataResult<>(queryUser);
            //再将这个对象呢?转换成json格式
            String jsonString = JSON.toJSONString(userDataResult);
            //最终进行数据的返回
​
            //设置编码 放置返回的数据有错误
            resp.setContentType("text/html;charset=utf-8");
            PrintWriter writer = resp.getWriter();
            writer.write(jsonString);
            writer.flush();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

1.3、编写结果集封装的这样一个接口

public interface IResponseCode {
​
    //这个是获取错误的信息
    String getMessage();
​
    //获取状态码
    int getCode();
}
​

1.4、编写结果集封装的这样一个枚举

/**
 * @author xiaobobo
 * @title: ResponceCode
 * @projectName cd2106projectparent
 * @description: 这个就是响应的错误或者正确信息的实例
 * @date 2021/8/1610:12
 */
public enum ResponceCode implements IResponseCode{
    SUCESS(0,"请求成功"),
    PARAMETER_ERROR(100,"参数异常"),
    USERNAME_ERROR(101,"用户名不对"),
    PASSWORD_ERROR(102,"密码不对"),
    SQL_ERROR(103,"SQL异常");
​
    ResponceCode(int code,String message){
        this.code=code;
        this.message=message;
    }
​
    private  int code;
    private String message;
​
​
    @Override
    public String getMessage() {
        return message;
    }
​
    @Override
    public int getCode() {
        return code;
    }
}
​

1.5、编写结果集封装的返回对象

@Data
public class DataResult<T> {
​
    private static int code;
    private static String message;
    private T t;
​
    public DataResult(){
        this.code=ResponceCode.SUCESS.getCode();
        this.message=ResponceCode.SUCESS.getMessage();
    }
​
    public DataResult(int code,IResponseCode responseCode,T t){
        this.code=responseCode.getCode();
        this.message=responseCode.getMessage();
        this.t=t;
    }
​
    public DataResult(int code,ResponceCode responseCode,T t){
        this.code=responseCode.getCode();
        this.message=responseCode.getMessage();
        this.t=t;
    }
​
    public DataResult(T t){
        this.code=ResponceCode.SUCESS.getCode();
        this.message=ResponceCode.SUCESS.getMessage();
        this.t=t;
    }
​
    public static void success(){
        code=ResponceCode.SUCESS.getCode();
        message=ResponceCode.SUCESS.getMessage();
    }
}

1.6、编写Java的实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private int id;
    private String userName;
    private String password;
    private String token;
}

1.7、编写业务异常

@Data
public class BusinessException extends RuntimeException {
    //返回的状态码(很多很多 表示的是成功  或者失败)
    private int code;
​
    //如果返回的错误那么这里返回的是错误的原因
    private String message;
​
    public BusinessException(int code,String message){
        super(message);
        this.code=code;
        this.message=message;
    }
}

1.8、编写JDBC的工具类

public class JdbcUtils {
    private static DruidDataSource dataSource=null;
    static {
        dataSource=new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///cd2106?useUnicode=true&characterEncoding=UTF-8");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
    }
    /**
     * 获取操作数据库的对象
     * @return
     */
    public static QueryRunner queryRunner(){
        return new QueryRunner(dataSource);
    }
​
}

1.9、编写请求参数封装的这样一个工具类

public class ObjectUtils {
​
    private static  ObjectUtils objectUtils=new ObjectUtils();
    private ObjectUtils(){
​
    }
    /**
     * 返回这个请求的参数封装成的Java对象
     * @param httpServletRequest
     * @param clazz
     * @param <T>
     * @return
     */
    public <T>  T  getParameterObject(HttpServletRequest httpServletRequest,Class<T> clazz) throws IllegalAccessException, InstantiationException, InvocationTargetException {
        //这个就是需要封装的Java的类的实例对象
        T t=clazz.newInstance();
        //接下来需要将请求的参数封装到这个实例对象中
        // httpServletRequest.getParameterMap() :是将前端传递的参数的map获取出来
        BeanUtils.populate(t,httpServletRequest.getParameterMap());
        return t;
    }
​
    /**
     * 获取当前类的实例
     * @return
     */
    public static  ObjectUtils getInstance(){
        return objectUtils;
    }
}

1.10、编写token生成的工具类

public class TokenUtils {
​
​
    /**
     * 这个就是生成token的地方
     * 这个加锁的目的 是为了防止并发的时候 生成的UUID一致
     *
     * synchronized:Java中的锁 可以分成两类
     *   一类:隐式锁
     *       加锁和解锁的过程是由JVM来完成的
     *   二类:显示锁
     *       加锁和解锁 是自己调用方法来完成的
     *
     * @return
     */
    public synchronized static String getToken() {
        String s = UUID.randomUUID().toString();
        return s;
    }
}

centos 挂载ntfs所需要的步骤 我就是在挂载2TB的时候发现的 linux挂载NTFS分区移动硬盘2010-09-23 16:35CentOS 挂载NTFS分区移动硬盘 1.uname -r 查看当前的linux内核版本. [root@localhost Desktop]# uname -r 2.6.18-128.el5 2.去http://www.linux-ntfs.org/下载与内核版本相同的ntfs补丁.具体的地址 3.安装补丁:kernel-module-ntfs-2.6.18-128.el5-2.1.27-0.rr.10.11.i686.rpm [root@localhost Desktop]# rpm -ivh kernel-module-ntfs-2.6.18-128.el5-2.1.27-0.rr.10.11.i686.rpm Preparing... ########################################### [100%] 1:kernel-module-ntfs-2.6.########################################### [100%] 4.使用fdisk -l查看硬盘的分区信息. 5.mkdir /mnt/xxx 在mnt文件夹里新建文件夹,分别对应于移动硬盘下的分区(xxx为文文件夹名) 如:mkdir /mnt/name1 对应于叫做name1的盘 6.mount -t ntfs /dev/sdyz /mnt/xxx 将移动硬盘下的各分区挂载在新建的文件夹里(sdyz为硬盘的分区号码) 如: [root@localhost Desktop]# mount -t ntfs /dev/sdc1 /mnt/TheLORD,OurGod 今天将USB移动硬盘挂在CentOS上准备将压缩包拷贝下来的。 结果挂载移动硬盘的时候却提示: mount: unknown filesystem type ‘ntfs’ 原因:Linux无法识别NTFS格式的分区。 解决: 因为刚刚将CentOS升级到了2.6.18-164.el5内核,无法使用Kernel NTFS Module挂载Windows下的NTFS分区(没有在开源站点上找到相应内核包),所以只有使用ntfs-3g来解决了。 打开ntfs-3g的下载站点,将最新稳定版(当前最新版本为ntfs-3g-2010.3.6)下载到CentOS,执行以下命令安装: 1、编译安装ntfs-3g: #./configure #make #make install [/code] 2、查看USB设备点: #fdisk -l Disk /dev/sdb: 60.0 GB, 60011642880 bytes 255 heads, 63 sectors/track, 7296 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sdb1 * 1 653 5245191 b W95 FAT32 /dev/sdb2 654 7295 53351865 f W95 Ext'd (LBA) /dev/sdb5 654 1958 10482381 b W95 FAT32 /dev/sdb6 1959 7295 42869421 7 HPFS/NTFS 3、挂载NTFS分区: #mount -t ntfs-3g /dev/sdb6 /mnt/win
### CentOS 7 创建共享文件夹并下载挂载工具解决方案 对于在 VMware 或 VirtualBox 中运行的 CentOS 7 虚拟机,要实现与 Windows 主机之间的文件共享功能,通常需要安装特定的工具来支持这一操作。 #### 安装必要的软件包 为了使 Linux 和 Windows 实现无缝资源共享,在 VMware 环境下的第一步是确保已经正确配置了 VMWare Tools 工具集。如果是在 Oracle VM VirtualBox 上,则需确认 Guest Additions 是否已成功部署。这些组件包含了用于访问主机系统的共享文件夹的支持程序[^1]。 当面对无法下载所需挂载工具的情况时,可以尝试通过官方源或者第三方可信资源获取所需的 RPM 包: ```bash yum update -y && yum install open-vm-tools-desktop fuse-virtiofs virtio-win-guest-tools.noarch -y ``` 这段命令会更新现有系统并将一些常用的虚拟化增强型驱动和服务加入到环境中去,其中包括但不限于 VirtIO 文件系统 (virtiofs),它允许更高效的磁盘 I/O 性能以及更好的兼容性和稳定性。 #### 配置共享文件夹路径映射关系 一旦上述准备工作就绪之后,接下来就是定义好想要同步的具体位置。假设已经在宿主操作系统上指定了一个名为 `shareCent` 的共享区域,并希望将其链接至 `/home/shareCent` 这样的本地目标点的话,那么就可以执行如下指令来进行绑定[^2]: ```bash sudo mkdir -p /home/shareCent sudo mount -t vboxsf shareCent /home/shareCent ``` 需要注意的是,这里的 `-t vboxsf` 参数适用于 VirtualBox 用户;而对于 VMware 用户来说则应采用不同的方式连接共享空间——即利用 vmhgfs-fuse 来代替传统的 NFS/CIFS 协议[^3]。 #### 排查常见错误原因 有时即使完成了以上步骤仍然看不到预期中的新添加项。这可能是由于网络延迟或者是缓存机制所引起的暂时现象。建议重新启动一次虚拟客户机再做观察。另外一种可能性在于是否按照规定流程先后顺序进行了相应设置:应当先于虚拟平台内部指定好待共享的目标对象,随后再到 guest OS 内部实施对应的加载动作。 #### 处理联网异常状况 假如遇到像 “ping:baidu.com: 未知的名称或服务” 类似的 DNS 查询失败提示信息,可能是因为缺少必要的解析器配置或是防火墙阻止了外部请求。此时可以通过编辑 `/etc/resolv.conf` 添加合适的 nameserver 地址(例如 Google Public DNS),同时开放 iptables 对 ICMP echo-reply 报文类型的许可权限[^4]。 ```bash echo 'nameserver 8.8.8.8' | sudo tee -a /etc/resolv.conf sudo systemctl restart NetworkManager firewall-cmd --add-rich-rule='rule protocol value="icmp" accept' ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值