目录
通过Spring简单实现前端和后端的交互
首先新建一个UserController类,里面放着会被前端访问的方法
前端界面点击登录按钮后,实际上是通过springboot访问后端的对应方法。通过Spring实现前后端交互
比如点击百度用户界面的登录按钮,按F12检查网页,到network下面,点击登录按钮会发现访问的是一个地址,类似于 http://master:3306/package/?login。
点击前端的按钮会通过这个地址,将输入的username和password的值,传入后端对应的登录检查方法login里面,检查输入值与数据库是否一致
要想绑定方法与前端地址,需要使用注解
这个类当中使用了两种注解:
-
@RestController 用于类,会把当前类与前端地址做一个绑定
@RestController = @Controller + @ResponseBody
@Controller的作用可以粗暴的理解为将类标记为Controller对象,并且在需要的时候将类实例化
@ResponseBody用于处理Controller对象里面方法返回的数据,通常以json的形式返回给客户端 -
@RequestMapping 用于方法,把类下面的方法与注解上的路径做一个绑定
@RequestMapping是将请求映射到特定处理程序方法的注释
也就是在这里的login方法前加上这个注释后
当我点击了登录按钮,就会根据一个地址,找到这个login登录检查方法。这个地址在这里是localhost:8080/login
这里的@RequestMapping 后面的参数是指定请求的实际地址
这里相当于跟上这个方法的相对路径,相对于这个类的路径
另外,注解后面的这个地址名不能相同,即使是在不同类的相同类的类名,也要换一个名称
package com.demo.spring.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@RequestMapping("/login")
public String login(){
System.out.println("login方法");
return "login";
}
@RequestMapping("/delete")
public String delete(){
System.out.println("delete方法");
return "delete";
}
}
运行Application方法
在地址栏输入相应的地址,就可以访问到指定的方法,也就是上面UserController类里面的login方法
也就是说前端通过 localhost:8080/login 这个地址找到了login方法,并获取了login方法的返回值
这里返回的数据,也可以不是字符串类型
package com.demo.spring.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
@RestController
public class UserController {
@RequestMapping("/delete")
public HashMap<String, String> delete(){
System.out.println("delete方法");
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("你好","世界");
hashMap.put("爱好","敲代码");
return hashMap;
}
}
@Controller与@RestController
类前面的注解是@RestController时,表明方法返回的是数据,具体例子看上面即可,返回的是一个字符串,内容为login
类前面的注解是@Controller时,表明方法返回的是一个页面
这里举一个例子,返回一个简单的html界面
package com.demo.spring.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserController2 {
@RequestMapping("/loginTest")
public String login(){
System.out.println("login方法");
//这里return后面跟着的test不是一个字符串
//而是一个html文件的名字
return "test";
}
}
前置工作:
- 写一个html文件(注意html文件位置)
- 配置文件 application.properties
这个文件的作用是,当方法返回的内容为一个页面时,会自动到指定路径下面查找,后缀名为.html的文件。如果不配置这个文件,方法是找不到html文件的。
- 配置pom.xml文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
都完成之后就可以关闭之前的Application程序,然后重新运行
在地址栏输入地址访问到相应方法后,就会自动跳转到html写的界面
使用MVC和三层架构来完成用户登录检查代码
MVC和三层架构有着类似的思想,都是分层,解耦
三层架构的三层分别是:
(具体解析可以看菜鸟教程——三层架构详解)
- 表现层(web层):主要是指与用户交互的界面。用于接收用户输入的数据和显示处理后用户需要的数据
- 业务逻辑层(service层):UI层和DAL层之间的桥梁。实现业务逻辑。业务逻辑具体包含:验证、计算、业务规则等等
- 数据访问层(dao层)(持久化层):与数据库打交道。主要实现对数据的增、删、改、查。将存储在数据库中的数据提交给业务层,同时将业务层处理的数据保存到数据库
最后还要加上一个数据库,就完成了三层架构的划分。这样的划分让代码结构更清晰,而且不同层可以由不同的人负责,比如前端工程师专注于表现层,让页面更加美观。而数据库工程师就专注于数据访问层,负责编写各种sql语句。
首先建好相应的包
具体的架构如下
mvc和util之间有一个test文件夹,忽视就行,那个是用来练习的
具体的代码为
bean层
用来存储dao层查询数据库后返回的数据
package com.demo.spring.mvc.bean;
import lombok.*;
//利用lombok的注解,按下面代码顺序分别代替get,set,有参构造,无参构造,toString方法
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {
private String id;
private String username;
private String password;
}
web层
本层逻辑为:
前端用户点击登录按钮后,跳转到这个方法
这个方法应该返回一个登录成功或者登录失败的结果
而这个结果是由业务逻辑层来决定的
package com.demo.spring.mvc.controller;
import com.demo.spring.mvc.service.UserService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
//表现层,用于前端和后端的交互
@RestController
public class UserController {
@RequestMapping("/loginController")
public String userlogin(String username,String password){
UserService userService = new UserService();
String message = userService.loginService(username,password);
return message;
}
}
service层
本层逻辑为:
先验证用户,如果验证失败直接return一个用户不存在的信息
验证用户成功后验证密码,如果失败return一个密码错误的信息
两个都验证通过,则返回一个登录成功的信息
具体如何验证信息,先从表现层那里拿到用户输入的username和password
再从Dao层拿到数据库存储的username和password
如果两个层的数据能对应上,则返回登录正确,否则返回登录错误等信息
package com.demo.spring.mvc.service;
import com.demo.spring.mvc.bean.User;
import com.demo.spring.mvc.dao.UserDao;
//业务逻辑层,只是用来验证登录成功还是登录失败
public class UserService {
public String loginService(String username,String password){
UserDao userDao = new UserDao();
User user = userDao.loginDao(username);
//1,判断用户是否存在
if(user==null){
return "用户不存在";
}
//2.判断用户存在后,继续判断密码
if(!user.getPassword().equals(password)){
return "密码错误";
}
return "登录成功";
}
}
dao层
本层逻辑为
查看数据库——>获取数据——>将数据存储一个类对象中——>返回这个对象
比如要查询username和password信息,那么创建一个类,类的实例属性就是id,username和password
具体返回的内容就类似于User(id,username,password),相当于将数据保存在这个类对象里面
因此还要再创建一个包bean,用来存放这个类
方法的参数只需要一个username,只因为具体的密码验证在service层
dao层只需要按照username从数据库中取出该行数据交给service层即可
package com.demo.spring.mvc.dao;
import com.demo.spring.mvc.bean.User;
import com.demo.spring.util.JDBCUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class UserDao {
public User loginDao(String username){
User user = null;
try {
JDBCUtil.getConn();
PreparedStatement ps = JDBCUtil.getPs("select * from userInfo where username=?");
ps.setString(1,username);
ResultSet rs = ps.executeQuery();
if(rs.next()){
//将user的初始化和赋值放入判断语句中
//如果按输入的username查询到了数据库数据,则将数据存入user对象中
//如果没有找到,那么user对象就是null
//这样写方便service层判断数据库中是否有输入的username对应的用户,判断user是不是null即可
user = new User();
user.setId("id");
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
}
} catch (SQLException e) {
e.printStackTrace();
}
return user;
}
}
注意这里不能关闭连接,不能使用JDBCUtil.closeAll,否则会报连接已经关闭,无法连接数据库的错误
如果想进行多次连接,可以用连接池进行改造
SpringBoot笔记 —— 数据库连接池
配置文件application.properties
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
JDBC工具类及mysql.properties配置文件
MySQL笔记 —— jdbc工具类(网站的修改密码,注册账号,注销账号功能)
最后运行Application程序
在这里输入username和password的信息
数据库的userInfo表里面的数据为
username和password均正确,因此显示登录成功
将密码修改成错误密码,看看结果会怎么变化
增加新的要求
此时如果我想增加新的需求,比如要求用户输入的username的长度必须包含 “root” 字符串
验证用户输入信息是在service层,因此只需要修改这一层的代码即可,这也是三层架构的优点所在,可以迅速找到对应功能的代码所在位置,并且只需要修改这一部分,而不影响到其他部分。
package com.demo.spring.mvc.service;
import com.demo.spring.mvc.bean.User;
import com.demo.spring.mvc.dao.UserDao;
public class UserService {
public String loginService(String username,String password){
UserDao userDao = new UserDao();
User user = userDao.loginDao(username);
//1.验证用户输入格式是否正确
//这里必须要在前面判断一下user是否为null,为null则逻辑运算符||短路执行
//不会因为用null调用contains方法出错
if(user==null || !user.getUsername().contains("root")){
return "当前用户格式错误";
}
// 正确则继续执行,否则输出格式错误
//2.判断用户存在后,继续判断密码
if(!user.getPassword().equals(password)){
return "密码错误";
}
return "登录成功";
}
}
使用root用户依旧能正常登录,那么使用数据库里面的show用户呢
提示了用户格式错误
至此,使用三层架构模拟网站用户登录完成