SpringBoot实现登录注册(ajax)

SpringBoot框架实现登录注册ajax

  • 日期
    • 1、项目分析,首先规划开发流程
    • 2、创建数据表
    • 3、先把application.properties配置写全
    • 4、首先第一步,进行持久层开发
    • 5、持久层测试
    • 6、业务层开发
    • 6、业务层测试
    • 7、控制器代码编写
    • 8、前端展示
          • register注册界面
          • login注册界面
          • index主页
    • 彩蛋:

日期

今天是 2019 / 10 / 23     13:32!

1、项目分析,首先规划开发流程

首先把流程先说一下:

       开发步骤: 持久层 > 业务层 > 控制器 > 前端界面  

如下:
SpringBoot实现登录注册(ajax)_第1张图片

差点忘了发添加的依赖:pom.xml内容



    4.0.0
   
    
    
        org.springframework.boot
        spring-boot-starter-parent
        2.2.0.RELEASE
         
    

    com.zhang
    demo_3
    0.0.1-SNAPSHOT
    demo_3
    Demo project for Spring Boot

   
    
        1.8
    

    
         
        
            com.fasterxml.jackson.core
            jackson-databind
            2.9.8
        

       
        
            org.springframework.boot
            spring-boot-starter
        
        
         
        
            org.springframework.boot
            spring-boot-starter-tomcat
            provided
        
        
         
        
            org.springframework.boot
            spring-boot-starter-web
        
        
         
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.1.0
        
        
         
        
            mysql
            mysql-connector-java
            runtime
        
        
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
            
                
                    org.junit.vintage
                    junit-vintage-engine
                
            
        
    
    
    
    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


2、创建数据表

    // 创建数据库user
	CREATE DATABASE user;
	USE user;
	
	//创建数据表users
	CREATE TABLE `users` (
	   `id` int(100) NOT NULL AUTO_INCREMENT COMMENT 'id',
	   `username` char(20) NOT NULL COMMENT '用户名',
	   `password` char(20) NOT NULL COMMENT '密码',
	   PRIMARY KEY (`id`)
	 ) ENGINE=InnoDB DEFAULT CHARSET=utf-8mb4;

数据表创建完成!!

3、先把application.properties配置写全

解释:第一行最后的 Shanghai也可以换成 Chongqing。上海、重庆。
mybatis插件需要标明扫描的是哪里的 xml内容。

   spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-  8&serverTimezone=Asia/Shanghai
   spring.datasource.username=root
   spring.datasource.password=root

   mybatis.mapper-locations=classpath:mappers/*.xml

4、首先第一步,进行持久层开发

1、先编写实体类,User实体类。为com.zhang.demo_3.entity下新建的User实体类!

package com.zhang.demo_3.entity;

import java.util.Objects;

public class User {

     //序列化版本号
    private static final long serialVersionUID = 1L;
    private Integer id;
    private String username;
    private String password;

     //getter和settte方法、tostring 等方法自己写 !!
 
}

2、在com.zhang.demo_3 下添加 mapper 包,添加 UserMapper 接口,为com.zhang.demo_3.mapper下的UserMapper接口。

内容如下:

注意:记得在接口前添加 @Mapper注解,用于表明这是持久层接口!

package com.zhang.demo_3.mapper;
	
import com.zhang.demo_3.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper {
    /**
     * 用户添加
     * @param user
     * @return
     */
    Integer insert(User user);

    /**
     * 查找用户名
     * @param username
     * @return
     */
    User findByUsername(String username);

    /** 
     * 根据id查找信息
     * @param id
     * @return
     */
    User findById(Integer id);

}

3、在 resource 目录下添加 mappers 包, 编写 UserMapper.xml 文件,

** 这是 resource目录下的com.zhang.demo_3下的mappers **

内容如下:

注意:resultType为使用的具体实体类,还可以使用 resultMap 作为返回值!






    
    
    
        INSERT INTO users(
            id,username,
            password
        )VALUES(
            #{id},#{username},
            #{password}
        )
    

    
    
    

    
    
    



5、持久层测试

1、在com.zhang.demo_3下新建mapper包,并添加UserMapperTest测试类。

解释:
这是测试mapper包下的 UserMapper接口和 UserMapper.xml是否能连接数据库进行查询 !!

	package com.zhang.demo_3.mapper;
	
	import com.zhang.demo_3.entity.User;
	import org.junit.Test;
	import org.junit.runner.RunWith;
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.boot.test.context.SpringBootTest;
	import org.springframework.test.context.junit4.SpringRunner;
	
	@SpringBootTest
	@RunWith(SpringRunner.class)
	public class UserMapperTest {
	
	    @Autowired(required=true)
	    private UserMapper userMapper;
	  
	   //测试添加数据
	    @Test
	    public void insert(){
	        User user=new User();
	        String username="zhangsan";
	        String password="123456";
	        Integer id=2;
	        user.setId(id);
	        user.setPassword(password);
	        user.setUsername(username);
	        Integer rows=userMapper.insert(user);
	        System.out.println(rows);
	    }
	   //测试查找用户名
	    @Test
	    public void findByUsername(){
	        String username="zhangsan";
	        User result=userMapper.findByUsername(username);
	        System.out.println(result);
	    }
	   //测试根据id查找内容
	    @Test
	    public void findById(){
	        Integer id=4;
	        User result=userMapper.findById(id);
	        System.out.println(result);
	    }
	
	}

SpringBoot实现登录注册(ajax)_第2张图片
只列举了一个。。有问题可以下方提问 !

这样持久层就完成了 !!开发业务层

6、业务层开发

(a) 规划异常

ServiceException :异常基类,便于后继处理!

package com.zhang.demo_3.service.ex;

public class ServiceException extends RuntimeException{

    public ServiceException() {
    }

    public ServiceException(String message) {
        super(message);
    }

    public ServiceException(String message, Throwable cause) {
        super(message, cause);
    }

    public ServiceException(Throwable cause) {
        super(cause);
    }

    public ServiceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

UsernameDuplicateException:检查用户名是否被占用,占用已注册!

	package com.zhang.demo_3.service.ex;
	
	public class UsernameDuplicateException extends ServiceException {
	
	    public UsernameDuplicateException() {
	    }
	
	    public UsernameDuplicateException(String message) {
	        super(message);
	    }
	
	    public UsernameDuplicateException(String message, Throwable cause) {
	        super(message, cause);
	    }
	
	    public UsernameDuplicateException(Throwable cause) {
	        super(cause);
	    }
	
	    public UsernameDuplicateException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
	        super(message, cause, enableSuppression, writableStackTrace);
	    }
	}

UsernameNotFoundException :用户名找不到,不可以登陆 !

package com.zhang.demo_3.service.ex;

public class UsernameNotFoundException extends ServiceException  {

public UsernameNotFoundException() {
}

public UsernameNotFoundException(String message) {
    super(message);
}

public UsernameNotFoundException(String message, Throwable cause) {
    super(message, cause);
}

public UsernameNotFoundException(Throwable cause) {
    super(cause);
}

public UsernameNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
    super(message, cause, enableSuppression, writableStackTrace);
    }
}

PasswordNotException :密码找不到,密码错误 !

package com.zhang.demo_3.service.ex;

public class PasswordNotException extends ServiceException{
    public PasswordNotException() {
}

public PasswordNotException(String message) {
    super(message);
}

public PasswordNotException(String message, Throwable cause) {
    super(message, cause);
}

public PasswordNotException(Throwable cause) {
    super(cause);
}

public PasswordNotException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
    super(message, cause, enableSuppression, writableStackTrace);
}

}

(b) 接口与抽象方法

1、创建 com.zhang.demo_3.service.IUserService业务层接口,并在接口中添加功能的抽象方法,关于业务层的抽象方法的设计原则:

返回值:仅以操作成功(例如注册成功,登录成功等)为前提来设计返回值;

方法名:自定义;

参数列表:控制器可提供的,通常是用户提交的数据,及Session中的数据;

抛出异常:所有操作失败(登录时用户名不存在,登录时密码错误,注册时用户名被占用等)对应的异常。

基于以上设计原则,此次“注册”的抽象方法应该是:在com.zhang.demo_3下新建service包,IUserService接口

解释:
这是一个业务层接口。

package com.zhang.demo_3.service;

import com.zhang.demo_3.entity.User;

public interface IUserService {

    /**
     * 用户注册
     * @param
     * @return
     */
    void reg(User user);

    /**
     * 用户登录
     * @param user
     * @return
     */
    User login(String username, String password);
    
}

© 实现业务
进行编写业务层实现类,在com.zhang.demo_3.service下新建一个包impl,用于存放业务层实现类。这里新建一个UserServiceImpl实现类!

注意:记得添加@Service注解,在类中声明持久层对象。

package com.zhang.demo_3.service.impl;

import com.zhang.demo_3.entity.User;
import com.zhang.demo_3.mapper.UserMapper;
import com.zhang.demo_3.service.IUserService;
import com.zhang.demo_3.service.ex.UsernameNotFoundException;
import com.zhang.demo_3.service.ex.PasswordNotException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServieImpl implements IUserService {

    @Autowired
    private UserMapper userMapper;

    //用户注册业务逻辑
    @Override
    public void reg(User user) {
        System.out.print(user.getUsername());
        System.out.print(user.getPassword());
        //判断用户名是否为null
        String username = user.getUsername();
        User result = userMapper.findByUsername(username);

        if(result != null){
            throw new UsernameNotFoundException("注册名被占用");
        }

        String password=user.getPassword();
        user.setUsername(username);
        user.setPassword(password);


        System.out.print(result);

        userMapper.insert(user);
    }
    
   //用户登录业务逻辑
    @Override
    public User login(String username, String password) {
        User result=userMapper.findByUsername(username);

        if(result == null){
             throw new UsernameNotFoundException("用户名不存在");
        }

        if(!password.equals(result.getPassword())){
            throw new PasswordNotException("密码错误");
        }

        User user =new User();
        user.setUsername(username);
        user.setPassword(password);

        return user;
    }
}

6、业务层测试

1、在 test测试下 com.zhang.demo_3下新建service包,然后建立 UserServiceTest测试类,
内容如下:

package com.zhang.demo_3.service;

import com.zhang.demo_3.entity.User;
import com.zhang.demo_3.mapper.UserMapper;
import com.zhang.demo_3.service.ex.ServiceException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest
@RunWith(SpringRunner.class)
public class UserServiceTest {

    @Autowired
    private IUserService userService;

    @Test
    public void reg(){
        User user=new User();
        String username="zhang";
        String password="123456";
        Integer id=3;
        user.setId(id);
        user.setPassword(password);
        user.setUsername(username);
        userService.reg(user);

    }

    @Test
    public void login(){
         try {
            String username="root";
            String password ="1234";
            User Result=userService.login(username, password);
            System.err.println(Result);

           } catch (ServiceException e) {
            System.err.println(e.getClass().getName());
            System.err.println(e.getMessage());
          }
    }
}

业务层开发完成,进入控制器开发步骤:

业务层测试失败:
SpringBoot实现登录注册(ajax)_第3张图片
业务层登录测试成功:
SpringBoot实现登录注册(ajax)_第4张图片

7、控制器代码编写

(a) 处理异常
先创建cn.tedu.store.util.JsonResult响应结果类型,并在其中声明需要它可以给客户的数据的属性:

package com.zhang.demo_3.util;

public class JsonResult {

    private Integer state;
    private T data;
    private String message;

    public JsonResult() {
        super();
    }

    /**
     * 返回异常信息
     * @param e
     */
    public JsonResult(Throwable e){
         this.message=e.getMessage();
    }

    /**
     * 返回状态码和data响应数据类型
     * @param state
     * @param data
     */
    public JsonResult(Integer state, T data) {
        this.state = state;
        this.data = data;
    }

    public JsonResult(Integer state, String message) {
        this.state = state;
        this.message = message;
    }

    public JsonResult(Integer state) {
        this.state = state;
    }
    
    //getter和setter方法。。。。
    
}

此次“注册”时,业务层的“注册”功能可能抛出UsernameDuplicateException或InsertException,这2种异常其实也不只是“注册”才会抛出,其它的某些功能也可能抛出同样的异常,SpringMVC框架提供了统一处理异常的机制,在编写控制器中处理请求的代码时,就不必再关注异常的问题,等同于控制器中处理请求时将异常抛出,由SpringMVC框架再去捕获相关异常,并进行处理即可!

可以在控制器中添加一个专门处理异常的方法,关于方法的设计原则:

权限:应该使用public权限;
返回值:使用与处理请求的方法相同的原则;
方法名称:自定义;
参数列表:至少包括1个异常类型的参数,表示将捕获并处理的异常,另外,根据需要,可以添加HttpServletRequest等参数,但是,并不能像处理请求的方法那样随意添加;
必须添加@ExceptionHandler注解。

所以,处理异常的方法的声明大致是:

@ExceptionHandler
public JsonResult handleException(Throwable ex) {

}

在com.zhang.demo_3下添加 controller包,创建com.zhang.demo_3.controller.BaseController,实现Serializable接口,将作为实体类的基类,由于该类不需要直接创建对象,其存在的价值就是被其它实体类继承,所以,应该使用默认权限,且使用abstract进行修饰:

以上方法必须在控制器类中,也只能作用于当前控制器类中处理请求时抛出的异常,为了使得所有控制器类抛出的异常都可以被处理,应该将以上处理异常的代码添加在控制器类的基类BaseController中:

package com.zhang.demo_3.controller;

import com.sun.org.apache.xml.internal.resolver.helpers.PublicId;
import com.zhang.demo_3.service.ex.PasswordNotException;
import com.zhang.demo_3.service.ex.ServiceException;
import com.zhang.demo_3.service.ex.UsernameDuplicateException;
import com.zhang.demo_3.service.ex.UsernameNotFoundException;
import com.zhang.demo_3.util.JsonResult;
import org.apache.tomcat.util.http.fileupload.FileUploadException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;

/**
 * 控制器基类
 */
public abstract class BaseController {

    /**
     * 返回成功状态码2000
     */
    public static final int SUCCESS=2000;

    @ExceptionHandler({ServiceException.class, FileUploadException.class})
    public JsonResult handleException(Throwable ex) {
    
        JsonResult jsonResult=new JsonResult<>(ex);

        if(ex instanceof UsernameDuplicateException){
             //用户名被占用  -  2002
             jsonResult.setState(2002);
        }else if(ex instanceof UsernameNotFoundException){
             //用户名找不到  -  2003
             jsonResult.setState(2003);
        }else if(ex instanceof PasswordNotException){
             //密码错误
             jsonResult.setState(2004);
        }
        //返回响应值
        return jsonResult;
	   }
}

如果不通过基类处理异常,也可以自定义某个类,在类之前添加@ControllerAdvice或@RestControllerAdvice也可以使得整个项目的所有控制器都应用该处理异常的做法!

编写UesrController类,创建com.zhang.demo_3.controller.UserController类。

注意:@RestController 必须写,里边有PostMapping和RequestMapping();
声明@Autowired private IUserService userService;业务层对象

	package com.zhang.demo_3.controller;
	
	import com.zhang.demo_3.entity.User;
	import com.zhang.demo_3.service.IUserService;
	import com.zhang.demo_3.util.JsonResult;
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.web.bind.annotation.PostMapping;
	import org.springframework.web.bind.annotation.RequestMapping;
	import org.springframework.web.bind.annotation.RestController;
	
	import javax.servlet.http.HttpSession;
	
	@RestController
	@RequestMapping("users")
	public class UserController extends BaseController{
	
	    @Autowired
	    private IUserService userService;
	
	    @PostMapping("reg")
	    public JsonResult reg(User user)  {
	        userService.reg(user);
	        return new JsonResult<>(SUCCESS);
	    }
	
	    @RequestMapping("login")
	    public JsonResult login(String username, String password, HttpSession session){
	        User data = userService.login(username,password);
	        session.setAttribute("uid",data.getId());
	        session.setAttribute("username",data.getUsername());
	
	        return new JsonResult<>(SUCCESS,data);
	    }
	}

完成后,可以通过http://localhost:8080/users/reg?username=json&password=1234进行测试注册。

上边我写的@PostMapping,不可以用这个网址测试。
可以改为@RequestMapping,进行测试。
如下:
SpringBoot实现登录注册(ajax)_第5张图片

8、前端展示

register注册界面



    
    注册页面
    




没有账号,进入登录界面
login注册界面



    
    登录页面
    




已有账号,进入注册界面
index主页



    
    主页


zhuce
denglu




简单的主页:
SpringBoot实现登录注册(ajax)_第6张图片
简单的登录:
SpringBoot实现登录注册(ajax)_第7张图片
简单的注册:
SpringBoot实现登录注册(ajax)_第8张图片

彩蛋:

https://www.bootschool.net/ascii-art/search
SpringBoot实现登录注册(ajax)_第9张图片
SpringBoot实现登录注册(ajax)_第10张图片
SpringBoot实现登录注册(ajax)_第11张图片

你可能感兴趣的:(框架)