目录
第一步环境搭建
后端:
前端:
第二步画流程图
web:
service:
dao层:
第三步前端代码的实现
这是开始的页面,接下来我们要到router路由下书写#login的路径
路由中的component在我们自己创建的views书写vue文件
#/success的success.vue文件
第四步:后端代码的实现
web层loginServer类
web层registerServlet类
service的userServiceImpl类
dao层
第五步测试
我们现在要使用vue,mybatis,mysql实现一个简单的登录注册页面功能
使用的数据库:
create table user(id int primary key auto_increment,username varchar(10) not null ,password varchar(20) not null ); insert into user values (null,'zhangsan','1234'),(null,'hema','134'),(null,'wangu','456');
第一步环境搭建
后端:
在idea创建web工程
创建成功
创建成功后把pom.xml文件中关于junit的依赖全部删除,我们不需要
接着在pom.xml中导入相关依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.hhh</groupId><artifactId>web4_zhuce</artifactId><version>1.0-SNAPSHOT</version><name>web4_zhuce</name><packaging>war</packaging><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.target>11</maven.compiler.target><maven.compiler.source>11</maven.compiler.source></properties><dependencies><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version></dependency><!-- mysql依赖 --><!--mysql 驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.46</version></dependency><!--mybatis依赖--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.1</version></dependency><!--添加slf4j日志api--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.20</version></dependency><!--logback-classic依赖--><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency><!--添加logback_core依赖--><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId><version>1.2.3</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><version>3.3.2</version></plugin></plugins></build> </project>
接着在resource目录下创建mybatis-config.xml文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><properties resource="jdbc.properties"></properties><environments default="development"><!--设置默认的环境development,也可以配置多环境开发--><environment id="development"><transactionManager type="JDBC"/><!--使用mybatis自带的连接池POOLED--><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><!--配置映射文件关联的参数--><mappers><!--扫描mapper--><package name="com.hhh.dao"/></mappers> </configuration>
创建jdbc.properties文件
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/day10 jdbc.username=root jdbc.password=123456
创建logback.xml文件
<?xml version="1.0" encoding="UTF-8"?> <configuration><!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径--><property name="LOG_HOME" value="D:/log"/><!-- 控制台输出 --><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><!-- 日志输出编码 --><Encoding>UTF-8</Encoding><layout class="ch.qos.logback.classic.PatternLayout"><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern></layout></appender><!-- 按照每天生成日志文件 --><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><Encoding>UTF-8</Encoding><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!--日志文件输出的文件名--><FileNamePattern>hhh/mybatisTest.log.%d{yyyy-MM-dd}.log</FileNamePattern><MaxHistory>30</MaxHistory></rollingPolicy><layout class="ch.qos.logback.classic.PatternLayout"><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern></layout><!--日志文件最大的大小--><triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">222<MaxFileSize>1MB</MaxFileSize></triggeringPolicy></appender><!-- 日志输出级别 --><root level="ALL"><!-- 注意:如果这里不配置关联打印位置,该位置将不会记录日志--><appender-ref ref="CONSOLE"/><appender-ref ref="FILE"/></root></configuration>
这样一来我们后端的环境搭建好了,我们可以启动一下,查看是否报错
然后我们在java目录中创建pojo包封装数据库表的类
在pojo包下创建出对应的类之后,把id的类型改成Long对象型
前端:
在vscode中创建vue工程
在终端命令中书写
vue init webpack work
生成完成
然后在package.json中导入axios依赖
npm install axios@^0.27.2
注意如果版本太高,npm run dev会报错
WAIT Compiling... 下午2:51:4294% asset optimizationERROR Failed to compile with 2 errors 下午2:51:43error in ./node_modules/axios/lib/platform/index.jsModule parse failed: Unexpected token (5:2) You may need an appropriate loader to handle this file type. | | export default { | ...utils, | ...platform | }@ ./node_modules/axios/lib/defaults/index.js 8:0-44@ ./node_modules/axios/lib/axios.js@ ./node_modules/axios/index.js@ ./src/main.js@ multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/main.jserror in ./node_modules/axios/lib/core/mergeConfig.jsModule parse failed: Unexpected token (6:69) You may need an appropriate loader to handle this file type. | import AxiosHeaders from "./AxiosHeaders.js"; | | const headersToObject = (thing) => thing instanceof AxiosHeaders ? { ...thing } : thing; | | /**@ ./node_modules/axios/lib/axios.js 6:0-48@ ./node_modules/axios/index.js@ ./src/main.js@ multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/main.js
之后再vue文件中使用axios时,需要在<script></script> 中加上import axios from 'axios';
把前端的端口号改成8090,不然于tomcat服务器冲突
这样一来我们的环境已经搭建完成
第二步画流程图
实现登录功能
我们会在浏览器页面输入http://localhost:8090来访问前端服务器,接着前端服务器使用axios把从浏览器接收的数据发送给后端服务器(一次请求和响应),再tomcat服务器中使用三层架构模型(web,service,dao)
web:
- 解决post请求的中文乱码问题
- 接收来自前端提交的请求参数
- 将请求参数封装到User实体类-->user
- 创建业务层对象service对象
- 使用业务层对象调用业务层的登录方法(login)-->User u=userService.login(user)
- 判断u是否为null
- 如果u=null,说明没有查到用户,登陆失败,响应给前端一个false
- 如果u不为null,说明查到用户,登录成功,响应true
service:
- 定义登录方法接收web传递的user对象,并返回给web层一个新的对象
- 在登录方法中根据MybatisUtil工具类获取mybatis会话对象
- 使用会话对象调用方法获取dao层的接口代理对象
- 使用接口代理对象调用接口的登录方法(会返回一个User对象),user作为参数传递
- 释放资源
- 直接返回查询到的User对象
dao层:
- 创建接口
- 在接口中定义登录方法
- 在方法上使用注解查询数据
第三步前端代码的实现
这是开始的页面,接下来我们要到router路由下书写#login的路径
注意:在路由的路径不用写#
路由中的component在我们自己创建的views书写vue文件
login.vue代码
<template><div id="app"><!-- v-model与user的username属性双向绑定 --><span id="err" style="display: none">用户名或者密码错误</span><input type="text" name="username" v-model="user.username"> <br> //使用双向绑定把表单数据与data中的user的username绑定<input type="password" name="password" v-model="user.password"> <br><button @click="send">登录</button></div> </template><script> //导入axios import axios from 'axios'; export default {data() {return {user:{username:'',password:''}, };},methods: {send() { //后端服务器的路径let url="http://localhost:8080/loginServlet";let params=`username=${this.user.username}&password=${this.user.password}`; //使用重音符,进行字符串拼接请求参数 //使用axios的post请求,将服务器地址,请求参数axios.post(url, params).then(res => {//console.log(res.data);if(res.data){location.href="#/success" //跳转到成功的页面}else{document.getElementById("err").style.display="block";document.getElementById("err").style.color="red";}});// .catch(error => {// console.error(error);// });}}} </script><style></style>
启动前端项目
可以发现username的数据已经与表单数据关联,注意username是data中的username
点击登录,并查看抓包
注意:抓包的username是 let params=`username=${this.user.username}&password=${this.user.password}`;
axios的请求参数左边的usernmae
后端使用request接收前端的数据就要使用username来获取
#/success的success.vue文件
#/register的register.vue文件
<template><div id="app"><!-- v-model与user的username属性双向绑定 --><span id="err" style="display:none">该用已经存在,注册失败</span><span id="su" style="display:none">注册成功</span><input type="text" name="username" v-model="user.username"> <br><input type="password" name="password" v-model="user.password"> <br><button @click="send">注册</button></div> </template><script> import axios from 'axios'; export default {data() {return {user:{username:'',password:''}, };},methods: {send() { //在config-index.js中已经配置了服务器的三要素let url="http://localhost:8080/registerServlet";let params=`username=${this.user.username}&password=${this.user.password}`;axios.post(url, params).then(res => {if(res.data){document.getElementById("su").style.display="block";document.getElementById("su").style.color="green";//location.href="#/success";}else{document.getElementById("err").style.display="block";document.getElementById("err").style.color="red";}}).catch(error => {console.error(error);});}}} </script><style></style>
第四步:后端代码的实现
先实现 //后端服务器的路径
let url="http://localhost:8080/loginServlet";
web层loginServer类
@WebServlet("/loginServlet")//要与前端的axios路径一致 public class loginServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//解决中文乱码问题request.setCharacterEncoding("utf-8");//接收前端提交的请求参数String username = request.getParameter("username");String password = request.getParameter("password");//封装成对象User user = new User();user.setUsername(username);user.setPassword(password);//创建业务层service层对象UserServiceImpl userService=new UserServiceImpl();//使用业务层对象调用业务层的登录方法User u=userService.login(user);//判断u是否为空if(u==null) {response.addHeader( "Access-Control-Allow-Origin","*");//允许所有来源访同response.addHeader( "Access-Control-Allow-Method","POST,GET");//允许访问的方式//u为null,说明没有查到用户,登陆失败,响应给前端一个falseresponse.getWriter().print(false);} else{response.addHeader( "Access-Control-Allow-Origin","*");//允许所有来源访同response.addHeader( "Access-Control-Allow-Method","POST,GET");//允许访问的方式//n不为null,说明存在用户,登录成功,响应一个trueresponse.getWriter().print(true);//会被axios的res对象的data接收}}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);} }
response.addHeader( "Access-Control-Allow-Origin","*");//允许所有来源访同
response.addHeader( "Access-Control-Allow-Method","POST,GET");//允许访问的方式这两行十分重要,不然会报错:
Access to XMLHttpRequest at ‘http://localhost:8080/xxx’ from origin ‘http://localhost:63342’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
web层registerServlet类
@WebServlet("/registerServlet") public class registerServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//处理中文请求乱码问题request.setCharacterEncoding("utf-8");//接收参数String password = request.getParameter("password");String username = request.getParameter("username");//封装成对象User user = new User();user.setUsername(username);user.setPassword(password);//创建业务层对象UserServiceImpl userService = new UserServiceImpl();//调用业务层对象的注册方法boolean result=userService.register(user);//判断结果对错if(result){response.addHeader( "Access-Control-Allow-Origin","*");//允许所有来源访同response.addHeader( "Access-Control-Allow-Method","POST,GET");//允许访问的方式response.getWriter().print(true);}else{response.addHeader( "Access-Control-Allow-Origin","*");//允许所有来源访同response.addHeader( "Access-Control-Allow-Method","POST,GET");//允许访问的方式response.getWriter().print(false);}}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);} }
service的userServiceImpl类
public class UserServiceImpl {//定义登录方法public User login(User user) {//获取MybatisUtil工具类SqlSession sqlSession = MybatisUtil.openSession();//使用会话对象调用方法获取dao层的接口代理对象UserMapper mapper=sqlSession.getMapper(UserMapper.class);//使用接口代理对象调用方法User u=mapper.login(user);//释放资源MybatisUtil.closeSqlSession(sqlSession);//直接返回User对象return u;}public boolean register(User user) {SqlSession sqlSession=null;try {//获取MybatisUtil工具类sqlSession = MybatisUtil.openSession();//使用会话对象调用方法或缺dao层的代理对象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//使用接口代理对象调用方法User u=userMapper.queryUserByUserName(user.getUsername());//返回结果if(u==null) {//没有改用户,可以注册userMapper.register(user);//提交事务sqlSession.commit();//返回结果return true;}else{return false;}} finally {//防止空指针重复释放if(sqlSession!=null){//释放资源MybatisUtil.closeSqlSession(sqlSession);}}} }
dao层
//创建接口 public interface UserMapper {//在接口中定义登录方法//在方法使用注解/*username=#{username}左边的是数据库的字段名右边是User类的成员变量*/@Select("select * from user where username=#{username} and password=#{password}")User login(User user);@Insert("insert into user(username, password) values (#{username},#{password});")int register(User user);/*关于mybatis入参:1.如果方法只有一个非pojo Map类型参数,mybatis底层没有处理,我们在#{}中的获取数据可以随便写,所以建议使用注解@Param("标识符")修饰参数,那么此时#{}的大括号只能书写@Param("标识符")的标识符*/@Select("select * from user where username=#{username}")User queryUserByUserName(@Param("username") String username); }
第五步测试
注册功能
登录: