精华内容
下载资源
问答
  • 用户注册

    千次阅读 2020-02-18 12:57:30
    所以接下来我们编写用户中心,实现用户的登录和注册功能。 用户中心的提供的服务: 用户注册 用户登录 用户个人信息管理 用户地址管理 用户收藏管理 我的订单 优惠券管理 这里我们暂时先实现基...
    • 创建用户中心
    • 了解面向接口开发方式
    • 实现数据校验功能
    • 实现短信发送功能
    • 实现注册功能
    • 实现根据用户名和密码查询用户功能

    1.创建用户中心

    用户搜索到自己心仪的商品,接下来就要去购买,但是购买必须先登录。所以接下来我们编写用户中心,实现用户的登录和注册功能。

    用户中心的提供的服务:

    • 用户的注册
    • 用户登录
    • 用户个人信息管理
    • 用户地址管理
    • 用户收藏管理
    • 我的订单
    • 优惠券管理

    这里我们暂时先实现基本的:注册和登录功能,其它功能大家可以自行补充完整。

    因为用户中心的服务其它微服务也会调用,因此这里我们做聚合。

    leyou-user:父工程,包含2个子工程:

    • leyou-user-interface:实体及接口
    • leyou-user-service:业务和服务

    1.1.创建父module

    创建

    在这里插入图片描述

    位置:

    在这里插入图片描述

    1.2.创建leyou-user-interface

    在leyou-user下,创建module:

    在这里插入图片描述

    在这里插入图片描述

    pom:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>leyou-user</artifactId>
            <groupId>com.leyou.user</groupId>
            <version>1.0.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.leyou.user</groupId>
        <artifactId>leyou-user-interface</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    
    </project>
    

    1.3.创建leyou-user-service

    创建module

    在这里插入图片描述

    在这里插入图片描述

    pom

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>leyou-user</artifactId>
            <groupId>com.leyou.user</groupId>
            <version>1.0.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.leyou.user</groupId>
        <artifactId>leyou-user-service</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
            </dependency>
            <!-- mybatis启动器 -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
            </dependency>
            <!-- 通用Mapper启动器 -->
            <dependency>
                <groupId>tk.mybatis</groupId>
                <artifactId>mapper-spring-boot-starter</artifactId>
            </dependency>
            <!-- mysql驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <dependency>
                <groupId>com.leyou.user</groupId>
                <artifactId>leyou-user-interface</artifactId>
                <version>1.0.0-SNAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
            </dependency>
        </dependencies>
    
    </project>
    

    启动类

    @SpringBootApplication
    @EnableDiscoveryClient
    @MapperScan("com.leyou.user.mapper")
    public class LeyouUserApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(LeyouUserApplication.class, args);
        }
    }
    

    配置:

    server:
      port: 8085
    spring:
      application:
        name: user-service
      datasource:
        url: jdbc:mysql://127.0.0.1:3306/leyou
        username: root
        password: root
        driver-class-name: com.mysql.jdbc.Driver
    eureka:
      client:
        service-url:
          defaultZone: http://127.0.0.1:10086/eureka
      instance:
        lease-renewal-interval-in-seconds: 5
        lease-expiration-duration-in-seconds: 15
    
    mybatis:
      type-aliases-package: com.leyou.user.pojo
    

    父工程leyou-user的pom:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>leyou</artifactId>
            <groupId>com.leyou.parent</groupId>
            <version>1.0.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.leyou.user</groupId>
        <artifactId>leyou-user</artifactId>
        <packaging>pom</packaging>
        <version>1.0.0-SNAPSHOT</version>
        <modules>
            <module>leyou-user-interface</module>
            <module>leyou-user-service</module>
        </modules>
    
    </project>
    

    1.4.添加网关路由

    我们修改leyou-gateway,添加路由规则,对leyou-user-service进行路由:

    在这里插入图片描述

    2.后台功能准备

    2.1.接口文档

    整个用户中心的开发,我们将模拟公司内面向接口的开发。

    现在假设项目经理已经设计好了接口文档,详见:《用户中心接口说明.md》

    在这里插入图片描述

    我们将根据文档直接编写后台功能,不关心页面实现。

    2.2.数据结构

    CREATE TABLE `tb_user` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      `username` varchar(50) NOT NULL COMMENT '用户名',
      `password` varchar(32) NOT NULL COMMENT '密码,加密存储',
      `phone` varchar(20) DEFAULT NULL COMMENT '注册手机号',
      `created` datetime NOT NULL COMMENT '创建时间',
      `salt` varchar(32) NOT NULL COMMENT '密码加密的salt值',
      PRIMARY KEY (`id`),
      UNIQUE KEY `username` (`username`) USING BTREE
    ) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8 COMMENT='用户表';
    

    数据结构比较简单,因为根据用户名查询的频率较高,所以我们给用户名创建了索引

    2.3.基本代码

    在这里插入图片描述

    2.3.1.实体类

    @Table(name = "tb_user")
    public class User {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        private String username;// 用户名
    
        @JsonIgnore
        private String password;// 密码
    
        private String phone;// 电话
    
        private Date created;// 创建时间
    
        @JsonIgnore
        private String salt;// 密码的盐值
    }
    

    注意:为了安全考虑。这里对password和salt添加了注解@JsonIgnore,这样在json序列化时,就不会把password和salt返回。

    2.3.2.mapper

    public interface UserMapper extends Mapper<User> {
    }
    

    2.3.3.Service

    @Service
    public class UserService {
    
        @Autowired
        private UserMapper userMapper;
    }
    

    2.3.4.controller

    @Controller
    public class UserController {
    
        @Autowired
        private UserService userService;
        
    }
    

    3.数据验证功能

    3.1.接口说明

    实现用户数据的校验,主要包括对:手机号、用户名的唯一性校验。

    接口路径:

    GET /check/{data}/{type}
    

    参数说明:

    参数 说明 是否必须 数据类型 默认值
    data 要校验的数据 String
    type 要校验的数据类型:1,用户名;2,手机; Integer 1

    返回结果:

    返回布尔类型结果:

    • true:可用
    • false:不可用

    状态码:

    • 200:校验成功
    • 400:参数有误
    • 500:服务器内部异常

    3.2.controller

    因为有了接口,我们可以不关心页面,所有需要的东西都一清二楚:

    • 请求方式:GET
    • 请求路径:/check/{param}/{type}
    • 请求参数:param,type
    • 返回结果:true或false
    /**
      * 校验数据是否可用
      * @param data
      * @param type
      * @return
      */
    @GetMapping("check/{data}/{type}")
    public ResponseEntity<Boolean> checkUserData(@PathVariable("data") String data, @PathVariable(value = "type") Integer type) {
        Boolean boo = this.userService.checkData(data, type);
        if (boo == null) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
        }
        return ResponseEntity.ok(boo);
    }
    

    3.3.Service

    public Boolean checkData(String data, Integer type) {
        User record = new User();
        switch (type) {
            case 1:
                record.setUsername(data);
                break;
            case 2:
                record.setPhone(data);
                break;
            default:
                return null;
        }
        return this.userMapper.selectCount(record) == 0;
    }
    

    3.4.测试

    我们在数据库插入一条假数据:

    在这里插入图片描述

    然后在浏览器调用接口,测试:

    在这里插入图片描述

    在这里插入图片描述

    4.阿里大于短信服务

    4.1.demo

    注册页面上有短信发送的按钮,当用户点击发送短信,我们需要生成验证码,发送给用户。我们将使用阿里提供的阿里大于来实现短信发送。

    参考课前资料的《阿里短信.md》学习demo入门

    4.2.创建短信微服务

    因为系统中不止注册一个地方需要短信发送,因此我们将短信发送抽取为微服务:leyou-sms-service,凡是需要的地方都可以使用。

    另外,因为短信发送API调用时长的不确定性,为了提高程序的响应速度,短信发送我们都将采用异步发送方式,即:

    • 短信服务监听MQ消息,收到消息后发送短信。
    • 其它服务要发送短信时,通过MQ通知短信微服务。

    4.2.1.创建module

    在这里插入图片描述

    在这里插入图片描述

    4.2.2.pom

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>leyou</artifactId>
            <groupId>com.leyou.parent</groupId>
            <version>1.0.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.leyou.sms</groupId>
        <artifactId>leyou-sms-service</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-amqp</artifactId>
            </dependency>
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>aliyun-java-sdk-core</artifactId>
                <version>3.3.1</version>
            </dependency>
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
                <version>1.0.0</version>
            </dependency>
        </dependencies>
    </project>
    

    4.2.3.编写启动类

    @SpringBootApplication
    public class LeyouSmsApplication {
        public static void main(String[] args) {
            SpringApplication.run(LeyouSmsApplication.class, args);
        }
    }
    

    4.2.4.编写application.yml

    server:
      port: 8086
    spring:
      application:
        name: sms-service
      rabbitmq:
        host: 192.168.56.101
        username: leyou
        password: leyou
        virtual-host: /leyou
    

    4.3.编写短信工具类

    项目结构:

    在这里插入图片描述

    4.3.1.属性抽取

    我们首先把一些常量抽取到application.yml中:

    leyou:
      sms:
        accessKeyId: JWffwFJIwada # 你自己的accessKeyId
        accessKeySecret: aySRliswq8fe7rF9gQyy1Izz4MQ # 你自己的AccessKeySecret
        signName: 乐优商城 # 签名名称
        verifyCodeTemplate: SMS_133976814 # 模板名称
    

    然后注入到属性类中:

    @ConfigurationProperties(prefix = "leyou.sms")
    public class SmsProperties {
    
        String accessKeyId;
    
        String accessKeySecret;
    
        String signName;
    
        String verifyCodeTemplate;
    
        public String getAccessKeyId() {
            return accessKeyId;
        }
    
        public void setAccessKeyId(String accessKeyId) {
            this.accessKeyId = accessKeyId;
        }
    
        public String getAccessKeySecret() {
            return accessKeySecret;
        }
    
        public void setAccessKeySecret(String accessKeySecret) {
            this.accessKeySecret = accessKeySecret;
        }
    
        public String getSignName() {
            return signName;
        }
    
        public void setSignName(String signName) {
            this.signName = signName;
        }
    
        public String getVerifyCodeTemplate() {
            return verifyCodeTemplate;
        }
    
        public void setVerifyCodeTemplate(String verifyCodeTemplate) {
            this.verifyCodeTemplate = verifyCodeTemplate;
        }
    }
    

    4.3.2.工具类

    我们把阿里提供的demo进行简化和抽取,封装一个工具类:

    @Component
    @EnableConfigurationProperties(SmsProperties.class)
    public class SmsUtils {
    
        @Autowired
        private SmsProperties prop;
    
        //产品名称:云通信短信API产品,开发者无需替换
        static final String product = "Dysmsapi";
        //产品域名,开发者无需替换
        static final String domain = "dysmsapi.aliyuncs.com";
    
        static final Logger logger = LoggerFactory.getLogger(SmsUtils.class);
    
        public SendSmsResponse sendSms(String phone, String code, String signName, String template) throws ClientException {
    
            //可自助调整超时时间
            System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
            System.setProperty("sun.net.client.defaultReadTimeout", "10000");
    
            //初始化acsClient,暂不支持region化
            IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou",
                    prop.getAccessKeyId(), prop.getAccessKeySecret());
            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
            IAcsClient acsClient = new DefaultAcsClient(profile);
    
            //组装请求对象-具体描述见控制台-文档部分内容
            SendSmsRequest request = new SendSmsRequest();
            request.setMethod(MethodType.POST);
            //必填:待发送手机号
            request.setPhoneNumbers(phone);
            //必填:短信签名-可在短信控制台中找到
            request.setSignName(signName);
            //必填:短信模板-可在短信控制台中找到
            request.setTemplateCode(template);
            //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
            request.setTemplateParam("{\"code\":\"" + code + "\"}");
    
            //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
            //request.setSmsUpExtendCode("90997");
    
            //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
            request.setOutId("123456");
    
            //hint 此处可能会抛出异常,注意catch
            SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
    
            logger.info("发送短信状态:{}", sendSmsResponse.getCode());
            logger.info("发送短信消息:{}", sendSmsResponse.getMessage());
    
            return sendSmsResponse;
        }
    }
    

    4.4.编写消息监听器

    接下来,编写消息监听器,当接收到消息后,我们发送短信。

    @Component
    @EnableConfigurationProperties(SmsProperties.class)
    public class SmsListener {
    
        @Autowired
        private SmsUtils smsUtils;
    
        @Autowired
        private SmsProperties prop;
    
        @RabbitListener(bindings = @QueueBinding(
                value = @Queue(value = "leyou.sms.queue", durable = "true"),
                exchange = @Exchange(value = "leyou.sms.exchange", 
                                     ignoreDeclarationExceptions = "true"),
                key = {"sms.verify.code"}))
        public void listenSms(Map<String, String> msg) throws Exception {
            if (msg == null || msg.size() <= 0) {
                // 放弃处理
                return;
            }
            String phone = msg.get("phone");
            String code = msg.get("code");
    
            if (StringUtils.isBlank(phone) || StringUtils.isBlank(code)) {
                // 放弃处理
                return;
            }
            // 发送消息
            SendSmsResponse resp = this.smsUtils.sendSms(phone, code, 
                                                         prop.getSignName(),
                                                         prop.getVerifyCodeTemplate());
            
        }
    }
    

    我们注意到,消息体是一个Map,里面有两个属性:

    • phone:电话号码
    • code:短信验证码

    4.5.启动

    启动项目,然后查看RabbitMQ控制台,发现交换机已经创建:

    在这里插入图片描述

    队列也已经创建:

    在这里插入图片描述

    并且绑定:

    在这里插入图片描述

    5.发送短信功能

    短信微服务已经准备好,我们就可以继续编写用户中心接口了。

    5.1.接口说明

    在这里插入图片描述

    这里的业务逻辑是这样的:

    • 1)我们接收页面发送来的手机号码
    • 2)生成一个随机验证码
    • 3)将验证码保存在服务端
    • 4)发送短信,将验证码发送到用户手机

    那么问题来了:验证码保存在哪里呢?

    验证码有一定有效期,一般是5分钟,我们可以利用Redis的过期机制来保存。

    5.2.Redis

    5.2.1.安装

    参考课前资料中的:《centos下的redis安装配置.md》

    在这里插入图片描述

    5.2.2.Spring Data Redis

    官网:http://projects.spring.io/spring-data-redis/

    在这里插入图片描述

    Spring Data Redis,是Spring Data 家族的一部分。 对Jedis客户端进行了封装,与spring进行了整合。可以非常方便的来实现redis的配置和操作。

    5.2.3.RedisTemplate基本操作

    Spring Data Redis 提供了一个工具类:RedisTemplate。里面封装了对于Redis的五种数据结构的各种操作,包括:

    • redisTemplate.opsForValue() :操作字符串
    • redisTemplate.opsForHash() :操作hash
    • redisTemplate.opsForList():操作list
    • redisTemplate.opsForSet():操作set
    • redisTemplate.opsForZSet():操作zset

    其它一些通用命令,如expire,可以通过redisTemplate.xx()来直接调用

    5种结构:

    • String:等同于java中的,Map<String,String>
    • list:等同于java中的Map<String,List<String>>
    • set:等同于java中的Map<String,Set<String>>
    • sort_set:可排序的set
    • hash:等同于java中的:`Map<String,Map<String,String>>

    5.2.4.StringRedisTemplate

    RedisTemplate在创建时,可以指定其泛型类型:

    • K:代表key 的数据类型
    • V: 代表value的数据类型

    注意:这里的类型不是Redis中存储的数据类型,而是Java中的数据类型,RedisTemplate会自动将Java类型转为Redis支持的数据类型:字符串、字节、二进制等等。

    在这里插入图片描述

    不过RedisTemplate默认会采用JDK自带的序列化(Serialize)来对对象进行转换。生成的数据十分庞大,因此一般我们都会指定key和value为String类型,这样就由我们自己把对象序列化为json字符串来存储即可。

    因为大部分情况下,我们都会使用key和value都为String的RedisTemplate,因此Spring就默认提供了这样一个实现:在这里插入图片描述

    5.2.5.测试

    我们在项目中编写一个测试案例,把课前资料中的redisTest.java导入到项目中

    在这里插入图片描述

    在这里插入图片描述

    需要在项目中引入Redis启动器:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    

    然后在配置文件中指定Redis地址:

    spring:
      redis:
        host: 192.168.56.101
    

    5.3.在项目中实现

    需要三个步骤:

    • 生成随机验证码
    • 将验证码保存到Redis中,用来在注册的时候验证
    • 发送验证码到leyou-sms-service服务,发送短信

    因此,我们需要引入Redis和AMQP:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
    

    添加RabbitMQ和Redis配置:

    spring:
      redis:
        host: 192.168.56.101
      rabbitmq:
        host: 192.168.56.101
        username: leyou
        password: leyou
        virtual-host: /leyou
    

    另外还要用到工具类,生成6位随机码,这个我们封装到了leyou-common中,因此需要引入依赖:

    <dependency>
        <groupId>com.leyou.common</groupId>
        <artifactId>leyou-common</artifactId>
        <version>${leyou.latest.version}</version>
    </dependency>
    

    NumberUtils中有生成随机码的工具方法:

    /**
     * 生成指定位数的随机数字
     * @param len 随机数的位数
     * @return 生成的随机数
     */
    public static String generateCode(int len){
        len = Math.min(len, 8);
        int min = Double.valueOf(Math.pow(10, len - 1)).intValue();
        int num = new Random().nextInt(
            Double.valueOf(Math.pow(10, len + 1)).intValue() - 1) + min;
        return String.valueOf(num).substring(0,len);
    }
    

    5.3.1.UserController

    在leyou-user-service工程中的UserController添加方法:

    /**
     * 发送手机验证码
     * @param phone
     * @return
     */
    @PostMapping("code")
    public ResponseEntity<Void> sendVerifyCode(String phone) {
        Boolean boo = this.userService.sendVerifyCode(phone);
        if (boo == null || !boo) {
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity<>(HttpStatus.CREATED);
    }
    

    5.3.2.UserService

    在Service中添加代码:

    @Autowired
    private StringRedisTemplate redisTemplate;
    
    @Autowired
    private AmqpTemplate amqpTemplate;
    
    static final String KEY_PREFIX = "user:code:phone:";
    
    static final Logger logger = LoggerFactory.getLogger(UserService.class);
    
    public Boolean sendVerifyCode(String phone) {
        // 生成验证码
        String code = NumberUtils.generateCode(6);
        try {
            // 发送短信
            Map<String, String> msg = new HashMap<>();
            msg.put("phone", phone);
            msg.put("code", code);
            this.amqpTemplate.convertAndSend("leyou.sms.exchange", "sms.verify.code", msg);
            // 将code存入redis
            this.redisTemplate.opsForValue().set(KEY_PREFIX + phone, code, 5, TimeUnit.MINUTES);
            return true;
        } catch (Exception e) {
            logger.error("发送短信失败。phone:{}, code:{}", phone, code);
            return false;
        }
    }
    

    注意:要设置短信验证码在Redis的缓存时间为5分钟

    5.3.3.测试

    通过RestClient发送请求试试:

    在这里插入图片描述

    查看Redis中的数据:

    在这里插入图片描述

    查看短信:

    在这里插入图片描述

    6.注册功能

    6.1.接口说明

    在这里插入图片描述

    基本逻辑:

    • 1)校验短信验证码
    • 2)生成盐
    • 3)对密码加密
    • 4)写入数据库
    • 5)删除Redis中的验证码

    6.2.UserController

    /**
     * 注册
     * @param user
     * @param code
     * @return
     */
    @PostMapping("register")
    public ResponseEntity<Void> register(User user, @RequestParam("code") String code) {
        Boolean boo = this.userService.register(user, code);
        if (boo == null || !boo) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
        }
        return new ResponseEntity<>(HttpStatus.CREATED);
    }
    

    6.3.UserService

    public Boolean register(User user, String code) {
        // 校验短信验证码
        String cacheCode = this.redisTemplate.opsForValue().get(KEY_PREFIX + user.getPhone());
        if (!StringUtils.equals(code, cacheCode)) {
            return false;
        }
    
        // 生成盐
        String salt = CodecUtils.generateSalt();
        user.setSalt(salt);
    
        // 对密码加密
        user.setPassword(CodecUtils.md5Hex(user.getPassword(), salt));
    
        // 强制设置不能指定的参数为null
        user.setId(null);
        user.setCreated(new Date());
        // 添加到数据库
        boolean b = this.userMapper.insertSelective(user) == 1;
    
        if(b){
            // 注册成功,删除redis中的记录
            this.redisTemplate.delete(KEY_PREFIX + user.getPhone());
        }
        return b;
    }
    

    此处使用了课前资料中的CodeUtils:

    在这里插入图片描述

    该工具类需要apache加密工具包:

    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
    </dependency>
    

    6.4.测试

    我们通过RestClient测试:

    在这里插入图片描述

    查看数据库:

    在这里插入图片描述

    查看redis中的信息也被删除

    6.5.hibernate-validate

    刚才虽然实现了注册,但是服务端并没有进行数据校验,而前端的校验是很容易被有心人绕过的。所以我们必须在后台添加数据校验功能:

    我们这里会使用Hibernate-Validator框架完成数据校验:

    而SpringBoot的web启动器中已经集成了相关依赖:

    在这里插入图片描述

    6.5.1.什么是Hibernate Validator

    Hibernate Validator是Hibernate提供的一个开源框架,使用注解方式非常方便的实现服务端的数据校验。

    官网:http://hibernate.org/validator/

    在这里插入图片描述

    hibernate Validator 是 Bean Validation 的参考实现 。

    Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint(约束) 的实现,除此之外还有一些附加的 constraint。

    在日常开发中,Hibernate Validator经常用来验证bean的字段,基于注解,方便快捷高效。

    6.5.2.Bean校验的注解

    常用注解如下:

    Constraint 详细信息
    @Valid 被注释的元素是一个对象,需要检查此对象的所有字段值
    @Null 被注释的元素必须为 null
    @NotNull 被注释的元素必须不为 null
    @AssertTrue 被注释的元素必须为 true
    @AssertFalse 被注释的元素必须为 false
    @Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
    @Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
    @DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
    @DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
    @Size(max, min) 被注释的元素的大小必须在指定的范围内
    @Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
    @Past 被注释的元素必须是一个过去的日期
    @Future 被注释的元素必须是一个将来的日期
    @Pattern(value) 被注释的元素必须符合指定的正则表达式
    @Email 被注释的元素必须是电子邮箱地址
    @Length 被注释的字符串的大小必须在指定的范围内
    @NotEmpty 被注释的字符串的必须非空
    @Range 被注释的元素必须在合适的范围内
    @NotBlank 被注释的字符串的必须非空
    @URL(protocol=,host=, port=,regexp=, flags=) 被注释的字符串必须是一个有效的url
    @CreditCardNumber 被注释的字符串必须通过Luhn校验算法,银行卡,信用卡等号码一般都用Luhn计算合法性

    6.5.3.给User添加校验

    我们在leyou-user-interface中添加Hibernate-Validator依赖:

    <dependency>
        <groupId>org.hibernate.validator</groupId>
        <artifactId>hibernate-validator</artifactId>
    </dependency>
    

    我们在User对象的部分属性上添加注解:

    @Table(name = "tb_user")
    public class User {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        @Length(min = 4, max = 30, message = "用户名只能在4~30位之间")
        private String username;// 用户名
    
        @JsonIgnore
        @Length(min = 4, max = 30, message = "密码只能在4~30位之间")
        private String password;// 密码
    
        @Pattern(regexp = "^1[35678]\\d{9}$", message = "手机号格式不正确")
        private String phone;// 电话
    
        private Date created;// 创建时间
    
        @JsonIgnore
        private String salt;// 密码的盐值
    }
    

    6.5.4.在controller上进行控制

    在controller中改造register方法,只需要给User添加 @Valid注解即可。

    在这里插入图片描述

    6.5.5.测试

    我们故意填错:

    在这里插入图片描述

    然后SpringMVC会自动返回错误信息:

    在这里插入图片描述

    7.根据用户名和密码查询用户

    功能说明

    查询功能,根据参数中的用户名和密码查询指定用户

    接口路径

    GET /query
    

    参数说明

    参数 说明 是否必须 数据类型 默认值
    username 用户名,格式为4~30位字母、数字、下划线 String
    password 用户密码,格式为4~30位字母、数字、下划线 String

    返回结果

    用户的json格式数据

    {
        "id": 6572312,
        "username":"test",
        "phone":"13688886666",
        "created": 1342432424
    }
    

    状态码

    • 200:注册成功
    • 400:用户名或密码错误
    • 500:服务器内部异常,注册失败

    7.1.controller

    /**
     * 根据用户名和密码查询用户
     * @param username
     * @param password
     * @return
     */
    @GetMapping("query")
    public ResponseEntity<User> queryUser(
        @RequestParam("username") String username,
        @RequestParam("password") String password
        ) {
            User user = this.userService.queryUser(username, password);
            if (user == null) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
            }
            return ResponseEntity.ok(user);
        }
    

    7.2.service

    public User queryUser(String username, String password) {
        // 查询
        User record = new User();
        record.setUsername(username);
        User user = this.userMapper.selectOne(record);
        // 校验用户名
        if (user == null) {
            return null;
        }
        // 校验密码
        if (!user.getPassword().equals(CodecUtils.md5Hex(password, user.getSalt()))) {
            return null;
        }
        // 用户名密码都正确
        return user;
    }
    

    要注意,查询时也要对密码进行加密后判断是否一致。

    7.3.测试

    在这里插入图片描述

    8.在注册页进行测试

    在注册页填写信息:

    在这里插入图片描述

    提交发现页面自动跳转到了登录页,查看数据库:

    在这里插入图片描述

    展开全文
  • 此方法修改完后是可以继续更新的,我今天刚更新的版本是457.30,日期11/09/2020 1. 首先把Nvidia程序退出,并且任务管理器结束所有行程。 ...2. 删除此目录下的文件 C:\Users\XXXXXX\AppData\Local\NVIDIA ...
  • 用户注册登录流程

    千次阅读 2019-07-18 14:09:13
    用户注册: 1.用户填写参数,移出鼠标效验手机号,登录账号,邮箱, 2.判断用户id是否是超级管理员用户,超级管理员是不允许修改的 3.随机生成盐,用户赋值盐 4.登录名+密码+盐 进行Md5Hash加密 加密后密码赋值用户 5.用户...

    用户注册:
    1.用户填写参数,移出鼠标效验手机号,登录账号,邮箱,
    2.判断用户id是否是超级管理员用户,超级管理员是不允许修改的
    3.随机生成盐,用户赋值盐
    4.登录名+密码+盐  进行Md5Hash加密 加密后密码赋值用户
    5.用户表插入数据用户数据
    6.与用户相关联表插入关联数据  如:岗位表,角色表

    修改:
    数据回显,查询用户关联表,岗位表,角色变返回回显数据
    保存修改,先删除之前的关联关系,在添加关联关系

    删除:
    做状态删除
     

    展开全文
  • 实现用户登录与用户注册的思路

    万次阅读 2018-09-17 10:19:23
    正常的主页面应该有两个功能,一个是用户登录,一个是用户注册用户注册比较来说简单一点,主页面单击用户注册按钮,直接定位到注册页面,填写用户名和密码等等,单击提交,到后台action页面进行逻辑判断,查询这...

    正常的主页面应该有两个功能,一个是用户登录,一个是用户注册。

    用户注册比较来说简单一点,主页面单击用户注册按钮,直接定位到注册页面,填写用户名和密码等等,单击提交,到后台action页面进行逻辑判断,查询这个用户名在数据库是否已经存在。
    两种情况,如果不存在,直接保存,重定向到登录页面。
    如果存在,直接抛异常,自定义异常信息用户已存在,在action中进行捕获,并且将错误信息放入到reqeust域中,并转发到注册页面,在注册页面进行显示。

    用户登录,主页面单击用户登录,将数据提交到后台action,获得用户信息与数据库中的数据对比。
    三种情况,如果账号密码匹配,直接将返回的对象保存早session域中,并重定向到系统列表页面,
    如果没找到账号名称,则抛出异常,定义信息用户名不存在,配置全局异常变量,转发到登录页面,并显示异常信息。
    如果名称跟密码不匹配,则抛出异常,定义信息密码错误,转发到登录页面,并显示异常信息。

    展开全文
  • 实现用户注册和登录

    万次阅读 多人点赞 2019-01-09 17:57:55
    最近一段学习了java web当中的一些知识,利用所学知识,实现了用户注册和登录功能,为了以后学习,写在这保存一下,方便以后用,也方便大家学习交流。 1.数据库设计 首先 根据需要,因为本次编程实现用户注册界面,...

    本文主要介绍一下实现用户登录和注册功能

    最近一段学习了java web当中的一些知识,利用所学知识,实现了用户注册和登录功能,为了以后学习,写在这保存一下,方便以后用,也方便大家学习交流。

    1.数据库设计

    首先 根据需要,因为本次编程实现用户注册界面,本次需要访问数据库,建立shopping数据库,在数据库里面创建表users,代码如下:

       DROP TABLE IF EXISTS `users`;
       CREATE TABLE `users` (
       `id` int(11) NOT NULL auto_increment,
      `userName` varchar(50) default NULL,
      `password` varchar(50) default NULL,
      `sex`  varchar(20) default NULL,
      `email` varchar(11) default NULL,
      `favorite` varchar(20) default Null,
      `introduce` varchar(500) default NULL,
       PRIMARY KEY  (`id`)
         ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
    

    2.连接数据库

    利用jdbc实现对数据库的连接,创建DBHelper.java来实现连接数据库功能的类

           df
      package util;
     import java.sql.*;//导入sql类
    
      //完成数据库的连接
    public class DBHelper {
    private static final String  driver="com.mysql.jdbc.Driver";
    private static final String  url="jdbc:mysql://localhost:3306/shopping?useUnicode=true&characterEncoding=UTF-8";
    private static final String userName="root";
    private static final  String password="";
    private static  Connection conn=null;
    //加载驱动
    static{
    	
    	try{
    		Class.forName(driver);   
    	}catch(Exception e){
    		e.printStackTrace();
    	}
    }
     public static Connection getConnection() throws Exception
    {
        //之前未连接,则进行连接
       if(conn==null){
    	   conn=DriverManager.getConnection(url,userName,password);
    	   return conn;
       }
       //已经连接,则直接返回
       return conn;
      
      }
    }
    

    3.创建User实体类

    按照创建Users表的各个属性,创建User实体类,代码如下:

     package entity;
     import java.util.*;
     public class Users
      {
       private int id;
       private String userName;
      private String password;
      private String  email;
      private String sex;
      private Date birthday;
      private String [] favorite;
      private String introduce;
      
    
    public int getId() {
    	return id;
    }
    public void setId(int id) {
    	this.id = id;
    }
    public String getUserName() {
    	return userName;
    }
    public void setUserName(String userName) {
    	this.userName = userName;
    }
    public String getPassword() {
    	return password;
    }
    public void setPassword(String password) {
    	this.password = password;
    }
    public String getEmail() {
    	return email;
    }
    public void setEmail(String email) {
    	this.email = email;
    }
    public String getSex() {
    	return sex;
    }
    public void setSex(String sex) {
    	this.sex = sex;
    }
    public Date getBirthday() {
    	return birthday;
    }
    public void setBirthday(Date birthday) {
    	this.birthday = birthday;
    }
    public String[] getFavorite() {
    	return favorite;
    }
    public void setFavorite(String[] favorite) {
    	this.favorite = favorite;
    }
    public String getIntroduce() {
    	return introduce;
    }
    public void setIntroduce(String introduce) {
    	this.introduce = introduce;
    }
      
      
    }
    

    4.数据库操作

    创建UserDao类,实现查询数据库的数据(用户登录的时候会用到)和向数据库里面插入新数据(注册账号时会用到)

           package dao;
    import java.io.PrintWriter;
    import java.sql.*;
    import java.util.ArrayList;
    
    import javax.xml.ws.Response;
    
    import com.sun.beans.editors.IntegerEditor;
    
    import entity.Users;
    import jdk.nashorn.internal.ir.RuntimeNode.Request;
    import util.DBHelper;
    
    public class UsersDao {
        
     public Users  getInfo(int id) throws SQLException{
    	 Connection connection=null;
    	 PreparedStatement statement=null;
    	 ResultSet resultSet=null;
    	 try {
    		 connection=DBHelper.getConnection();
    		 String sql="select * from users where id=?";
    		 statement=connection.prepareStatement(sql);
    		 statement.setInt(1, id);
    		 resultSet=(ResultSet)statement.executeQuery();
    		 String [] str;
    		 if(resultSet.next()){
        	      Users  it=new Users();
        	      it.setId(resultSet.getInt("id"));
                  it.setUserName(resultSet.getString("userName"));
                  it.setPassword(resultSet.getString("password"));
                  it.setEmail(resultSet.getString("email"));
                  it.setSex(resultSet.getString("sex"));
                  it.setIntroduce(resultSet.getString("introduce"));
                   str=resultSet.getString("favorite").split("\\^");
                   if(str.length>0){
                   it.setFavorite(str);
                   }
               return it;
           }else{
        	   return null;
           }
    	} catch (Exception e) {
    		// TODO: handle exception
    		e.printStackTrace();
    		return null;
    	}finally{
    		if(resultSet!=null){
    			resultSet.close();
    			resultSet=null;
    		}
    		if(statement!=null){
    			 statement.close();
    			 statement=null;
    		}
    	
    		
    	}
     }
     
     
     public boolean setUserInfo(Users users) throws SQLException{
    	 
    	 Connection connection=null;
    	 PreparedStatement statement=null;
    	 String str="";
         
    	 try {
    		 connection=DBHelper.getConnection();
    		 String sql="insert into users(id,userName,password,sex,email,introduce,favorite) values(?,?,?,?,?,?,?)";
    		 statement=connection.prepareStatement(sql);
    		 statement.setInt(1, users.getId());
    		 statement.setString(2, users.getUserName());
    		 statement.setString(3, users.getPassword());
    		 statement.setString(4, users.getSex());
             statement.setString(5, users.getEmail());
             statement.setString(6, users.getIntroduce());
             String [] s=users.getFavorite();
               if(s!=null&&s.length>0){
               for(int i=0;i<s.length;i++){
            	   if(i==s.length-1){
            		   str+=s[i];
            	   }else{
            		   str+=s[i]+"^";
            	   }
            	  
               }
               }
               statement.setString(7, str);
    		 statement.executeUpdate();
               return true;
    	} catch (Exception e) {
    		// TODO: handle exception
    		e.printStackTrace();
    		return false;
    	}finally{
    	
    	     
    	}
     }
    

    }

    5.创建登录界面和注册界面

    5.1 登录界面

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     <link href="css/login.css" type="text/css"  rel="stylesheet"/>
     <link rel="stylesheet" href="http://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
     <script src="http://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
     <script src="http://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <title>Insert title here</title>
    </head>
    <body class="body">
    
    <center>
    <h1>登录界面</h1>
    <hr>
    <table>
     <tr>
     <form   action="servlet/LogIn" method="post" name="loginForm" class="form-inline">
        <tr >
         <td>标识:<input type="text" name="id2" placeholder="ID" class="form-control"/></td>
        </tr>
        <tr >
          <td>密码:<input type="password" name="passwd" placeholder="password"  class="form-control"/></td>
        </tr>
        <tr>
        <td>
        <p></p>
        <p></p>
        </td>
        </tr>
        <tr class="button">
          <td ><input type="submit" value="登录"   class="btn btn-primary" /></td>
          </tr>
     </form>
     <td>
     </td>
      <td><a href="index.jsp" style="font-size:18px;">注册</a>
      </td>
      </tr>
    
     </table>
     </center>
    </body>
    </html>
    

    对应的创建servlet Login.java,来实现对提交的表单进行处理(通过查询数据库实现验证用户的密码和账户是否正确一致):

      package servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import dao.UsersDao;
    import entity.Users;
    
    /**
     * Servlet implementation class LogIn
     */
    @WebServlet("/LogIn")
    public class LogIn extends HttpServlet {
    	private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public LogIn() {
            super();
            // TODO Auto-generated constructor stub
        }
    
    	/**
    	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
    	 */
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// TODO Auto-generated method stub
    		doPost(request, response);
    	}
    
    	/**
    	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
    	 */
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// TODO Auto-generated method stub
    		  request.setCharacterEncoding("utf-8");
              response.setContentType("text/html;charset=utf-8");
    		  int id;
    	      String passwd;
    		try {
    			 UsersDao usersDao=new UsersDao();
    			 id=Integer.parseInt(request.getParameter("id2"));  //捕获输入的id
                 passwd=request.getParameter("passwd");	  //捕获输入的密码
                 Users users=usersDao.getInfo(id);
                 if(users==null){  //打印用户不存在信息
                	 PrintWriter ps=response.getWriter();
                	 ps.println("<strong>该用户不存在!!!</strong>");
                	 
                 }else{
                	 if(passwd.equals(users.getPassword())){
                		 request.getRequestDispatcher("../page1.jsp").forward(request, response);
                	 }else{
                		 PrintWriter ps1=response.getWriter();
                    	 ps1.println("<strong>id和密码输入不正确!!!</strong>");
                	 }
                	
                 }
                  
    			
    		} catch (Exception e) {
    			// TODO: handle exception
    		}
    		
    		
    	}
    
    }
    

    4.2注册界面

       <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <link rel="stylesheet" href="http://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
     <script src="http://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
     <script src="http://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <title>Insert title here</title>
    </head>
    <body>
    <center>
    <h1>注册</h1>
    
    <form action="servlet/HelloServlet" method="post" name="register">
    
    <table>
       <tr >
       <td><input type="text" name="id1"  class="form-control" placeholder="ID"/></td>
       </tr>
      <tr>
      <td><input type="text" name="userName" placeholder="Username" class="form-control"/></td>
      </tr>
      <tr>
      <td><input type="password" name="password" class="form-control"  placeholder="password"/></td>
      </tr>
      <tr>
         <td><input type="text" name="email" class="form-control" placeholder="Email"/></td>
      </tr>
      <tr>
        <td ><label>性别:</label>
           <label><input type="radio"  name="sex"  value="boy"  />男</label>
            <label><input  type="radio" name="sex"  value="girl"/>女</label> 
        </td>
      </tr>
      <tr>
      
        <td>
          <label for="name">兴趣:</label>
            <label  class="checkbox-inline"><input type="checkbox" name="favorite" value="swimming" />游泳</label>
            <label  class="checkbox-inline"><input type="checkbox" name="favorite"  value="movie"/>看电影</label>
            <label  class="checkbox-inline"> <input type="checkbox" name="favorite"  value="play " />打球</td></label>
      </tr>
      <tr>
      <td>简介:</td>
      </tr>
      <tr>
      <td>
      <textarea rows="10" cols="40" name="introduce" class="form-control">
        
        </textarea>
        </td>
      </tr>
      <tr >
      <td><input type="submit" value="注册" class="btn btn-primary"/></td>
      </tr>
    </table>
    </form>
      <a  href="search.jsp">需要搜索的用户</a>
    </center>
    </body>
    </html>
    

    创建servlet HelloServlet.java实现对注册界面提交的表单进行处理

    package servlet;
    
    import java.io.IOException;
    import java.text.*;
    import java.io.PrintWriter;
    import java.nio.charset.Charset;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.websocket.Session;
    import javax.xml.ws.Response;
    
    import org.apache.catalina.User;
    import org.omg.PortableServer.REQUEST_PROCESSING_POLICY_ID;
    
    import dao.UsersDao;
    import entity.Users;
    
    public class HelloServlet extends HttpServlet {
    
    	@Override
    	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		// TODO Auto-generated method stub
    		
    		doPost(req, resp);
    	}
    
    	@Override
    	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		// TODO Auto-generated method stub
         
    		req.setCharacterEncoding("utf-8");
    		resp.setContentType("text/html;charset=utf-8");
    		Users users=new Users();
    		   int id;
    		   String userName;
    		   String password;
    		   String  email;
    		   String sex;
    		   Date birthday;
    		   String [] favorite;
    		   String introduce;
    		   
    		try {
    			//SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
    			id=Integer.parseInt(req.getParameter("id1"));
    			userName=req.getParameter("userName");
    			password=req.getParameter("password");
    			email=req.getParameter("email");
    			sex=req.getParameter("sex");
    			introduce=req.getParameter("introduce");
    			favorite=req.getParameterValues("favorite");
    			users.setId(id);
    			users.setUserName(userName);
    			users.setPassword(password);
    			users.setEmail(email);
    			users.setSex(sex);
    			users.setIntroduce(introduce);
    			users.setFavorite(favorite);
    		
    			UsersDao usersDao=new UsersDao();
    			Users users2=usersDao.getInfo(users.getId());
    			if(users2==null){
    				
    			boolean u=usersDao.setUserInfo(users);
    			//users.setFavorite(favorite);
    			//users.setBirthday(birthday);
    			if(u){
    				req.getSession().setAttribute("regUsers", users);
    			req.getRequestDispatcher("../userInfo.jsp").forward(req, resp);
    			
    			}else{
    		     PrintWriter out=resp.getWriter();
    		     resp.setContentType("text/html;charset=utf-8");
    		     out.println("<strong>fail</strong>");
    			}
    			}else{
    				PrintWriter out2=resp.getWriter();
    				resp.setContentType("text/html;charset=utf-8");
    				out2.println("<strong><center>该用户id已经存在,请重新输入</center></strong>");
    			}
    			
    		} catch (Exception e) {
    			// TODO: handle exception
    			e.printStackTrace();
    		}
    	}
    
    }
    

    结尾

    以上就实现了用户登陆和注册界面,下面展示一下

    在这里插入图片描述

    注册成功

    在这里插入图片描述

    登录界面

    在这里插入图片描述

    登录成功

    在这里插入图片描述

    展开全文
  • Java 实现用户注册登陆

    千次阅读 2018-10-24 14:57:19
    一个用户注册登陆的系统,用到了MD5加密处理密码,实现了一个简单的数据库连接池connectionPool, 实现了注册,登陆,登陆之后修改用户信息等功能,非常适合初学者 一.准备工作 数据库:MySQL 5.5.62-log MySQL ...
  • 先上效果图吧平面泡沫立体泡沫之前想做动态泡泡的效果,在网上没有搜到类似的样式。所以自己做了一个发上来,给有需要的人参考参考。代码部分有疑问或者有错请在评论指出,尽量...代码部分:&lt;!...gt; &...title&am
  • java用户注册界面

    千次阅读 2018-08-15 17:57:25
     * 功能:用户注册界面(Swing组件————复选框和单选框组件)  * 1.复选框组件:JCheckBox  * 2.单选框组件:JRadioButton  */ package com.gui; import java.awt.GridLayout; import javax.swing....
  • WordPress 用户注册和发送邮件

    万次阅读 2018-08-12 02:19:15
    新搭建的WordPress站点默认不开放用户注册功能,需要管理员登陆系统进行相应的配置,使WordPress支持用户注册功能。同时,WordPress默认禁用了发送邮件功能,所以还要通过相应的配置使系统能向用户发送注册邮件。 ...
  • * Description: 在用户注册时候,有的需要填写注册邮箱,那么完成用户注册之后,如何跳转到用户注册的邮箱所在的网址呢?使用如下封装方法获取地址 * * * @param registerEmail * @return 用户注册使用...
  • 用户注册页面的设计与实现

    千次阅读 2020-10-21 18:20:46
    用户注册页面的设计与实现 功能介绍: 1.使用HTML5表单技术实现用户注册页面,要求用户可以输入用户名、密码、真实姓名和电子邮箱等信息进行注册。 2.验证要求:每个输入栏目的文本框均需要显示提示信息。用户在点击...
  • 用户注册模块详解

    千次阅读 2016-08-18 11:56:43
    由于工作需要,对方要求me做个模块或者其他实体东西,于是就选择了大家经常用到的用户注册模块,废话不多说先看效果图,没有经过任何美工处理,效果一般,效果图: 在设计注册模块之前需要先知道此模块的工作...
  • 原生js用户注册界面

    千次阅读 2016-09-16 12:21:57
    原生js用户注册界面
  • woocommerce 开启用户注册功能

    千次阅读 2019-03-14 09:41:03
    最近在帮朋友开发外贸网站,基于wordpress的woocommerce插件,需要开启用户注册功能,发现只要修改下配置即可, 首先登录你的Wordpress管理员帐号,并进入管理后台,点击左侧菜单栏的“设置”--“常规” 在打开...
  • HTML实现用户注册界面

    万次阅读 多人点赞 2017-08-21 18:48:01
    <!DOCTYPE html> 用户注册页面 注册页面 <form action="#" method="get">
  • 用户注册账户的页面:用户的登录页面: 用户注册账户的页面: 对于上面的网页布局应该如何进行制作? <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name=...
  • SSM用户注册登录案例

    千次阅读 2019-07-09 10:48:01
    SSM用户注册登录案例 1. ssm配置 web.xml <!-- 配置前端控制器:服务器启动必须加载,需要加载springmvc.xml配置文件 --> <servlet> <servlet-name>dispatcherServlet</servlet-name> ...
  • thinkphp 5.0 用户注册登录

    千次阅读 2018-05-03 12:15:07
    1 ,控制器 创建控制器,写注册方法用户登录方法2、模型创建3,创建视图用户注册页面HTML用户登录页面HTML4 效果5 页面中访问注意:thinkPHP5 这两天刚看,验证规则错误返回,只返回错误信息,没有返回具体哪个...
  • php用户注册表单验证

    千次阅读 2016-10-19 21:33:12
    注册界面 register.html 用户注册 性别: 男 女 注册 register_verify.php require "mysql.php"; //导入m
  • Django实现用户注册登录

    千次阅读 2018-05-22 17:51:42
    学习Django中:写一个用户注册登录系统,开始搞事情 =====O(∩_∩)O~===== ================= Ubuntu python 2.7.12 Django 1.10.4 IDE:Pycharm Bootstrap ================= 新建项目:(我是直接用...
  • PHP 用户注册与登录

    千次阅读 2016-07-29 02:26:20
    网站用户注册与登录是很常用的一个功能,本节教材就以此来演示一下 PHP 中如何开发用户注册与登录模块。 本节需要用到的重点 PHP 基础知识: PHP 中预定义 $_POST 和 $_GET 全局变量来接受用户表单和 URL 参数信息...
  • Python-Flask构建用户注册登录后端逻辑架构 1、项目结构 2、app.py from flask import Flask,render_template from controller.user_controller import user_controller from datetime import timedelta import os ...
  • wordpress短代码显示用户注册日期

    千次阅读 2020-08-21 08:44:43
    如果你的网站提供用户注册的功能,你可能会在某种程度上希望能够显示用户的注册登记日期。以下是一个超级简单的代码片段,将显示特定用户的登记日期。这里我们使用了wp的短代码函数功能。 首先,在你主题的functions....
  • 网上很多Django关于实现用户注册与登录的教程都是用Django 1.X写的,比较老了,所以小编我觉得有必要亲自动手用Django 2.0重写用户注册与登陆教程。另外网上很多教程忽略了Django Auth模块自带的User模型而重新建立...
  • html 编写用户注册界面

    千次阅读 2018-10-01 22:49:56
    编写用户注册界面(友好型并通过js校验信息是否合法) &lt;!DOCTYPE html&gt; &lt;html lang="en"&gt; &lt;head&gt; &lt;meta charset="UTF-8"&gt; &lt;...
  • 用户注册协议

    千次阅读 2018-11-11 10:58:17
    本协议是用户(下称“您”),包括注册用户及没注册的访客(访客适用部分条款的约束),以注册、访问或浏览方式使用《*****》的产品和服务时与我们签署的协议(以下提到《愿者行》时即指该产品)。 请留意:您对《*...
  • 序言 对于一个网站而言,用户注册登录系统的重要性...本文结合工程实践,对用户注册登录系统可能面临的攻击和风险点逐一进行分析,并给出对应的应对措施,最终得到一套切实可行的用户注册登录设计方案。 五...
  • servlet用户注册页面前两种输入为空和已注册情况都成功了,但往数据库插入新的数据不成功,求各位大神帮我看下哪里的问题
  • 【JavaMailWeb】用户注册通过邮箱激活案例

    万次阅读 多人点赞 2016-08-22 17:49:16
    前面刚刚学习了JavaMail技术,现在来应用到项目中试试~网站用户注册:主要实现如下两个功能: 1、用户在网站上注册完成后给用户发一封邮件。 2、用户通过邮件激活后才可以登录。思路:首先需要一个思路:用户在前台...
  • jsp+javabean:实现用户注册功能

    千次阅读 2019-11-05 12:55:09
    要求编写一个 JavaBean封装用户注册信息 本文是我在学习javabean时的一些学习经验。 JavaBean是一个可重复使用的软件组件,是遵循一定标准,用JAVA语言编写的一个类,该类的一个实例成为一个Javabean,简称bean。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 100,894
精华内容 40,357
关键字:

用户注册