目錄
第一步環境搭建
后端:
前端:
第二步畫流程圖
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); }
第五步測試
?注冊功能
登錄: