SpringBoot項目實戰(初級)

目錄

一、數據庫搭建

二、代碼開發

1.pom.xml

2.thymeleaf模塊處理的配置類

3.application配置文件

4.配置(在啟動類中)

5.編寫數據層

②編寫dao層

③編寫service層

接口

?實現類

注意

補充(注入的3個注解)

1.@AutoWired(類型注入)

2.@Qualifier(名稱注入)

3.@Qualifier

?④編寫controller層

前端頁面

1.add.html

2.header.html

3.index.html

4.login.html

5.main.html

6.menu.html

7.update.html

css

1.header.css

2.login.css

3.menu.css

4.style.css

?controller代碼

⑤編寫攔截類

三、測試


搭建一個簡單的登錄攔截頁面。

首先,先來看一下最終的目錄結構:

最終目錄結構

一、數據庫搭建

這里演示案例用的是MySQL數據庫,并且數據庫名稱和表格結構如下所示?:

?可以通過手動圖形點擊的方式實現;或是打開一個查詢頁面,然后輸入下面的SQL語句:

-- 創建數據庫(如果尚未存在)
CREATE DATABASE IF NOT EXISTS boot_demo;
-- 使用數據庫
USE boot_demo;
-- 創建表格
CREATE TABLE IF NOT EXISTS txperson (pid INT PRIMARY KEY,username VARCHAR(255) NOT NULL,password VARCHAR(255) NOT NULL,p_addr INT,pname VARCHAR(255),gender INT,birth DATE
);

二、代碼開發

首先創建一個springboot項目,詳細步驟參見下面這篇文章(任選里面一種即可):

SpringBoot(一)--搭建架構5種方法_springboot框架搭建-CSDN博客文章瀏覽閱讀2.2k次,點贊19次,收藏39次。Spring Boot 是基于 Spring 框架,以約定優于配置、自動配置為核心,可快速構建獨立運行的應用,為微服務等開發提供便利的開發框架。前面已經對SSM(Spring,SpringMVC,MyBatis)每個框架做了講解,SpringBoot就是基于這個框架一個更簡單、更有利于開發。_springboot框架搭建 https://blog.csdn.net/m0_74977981/article/details/146139845?spm=1001.2014.3001.5502

1.pom.xml

首先導入項目所需要的依賴;這是在搭建一個項目后開始寫代碼之前的第一步驟。

怎么在maven中央倉庫找到自己需要的代碼和版本參見下面這篇文章的這一部分:

SSM項目的基本目錄結構_ssm框架項目的工程目錄-CSDN博客文章瀏覽閱讀662次,點贊19次,收藏21次。一個完整的SSM(Spring+SpringMVC+MyBatis)項目理應包含以下幾個目錄結構:上面是一個普通的maven項目。_ssm框架項目的工程目錄 https://blog.csdn.net/m0_74977981/article/details/145968984?spm=1001.2014.3001.5502#t17這里我的jdk版本的1.8即Java8;springboot框架是2.7.0版本,老規矩我會將演示案例的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><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.0</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>cn.tx.springboot</groupId><artifactId>tx_sys</artifactId><version>0.0.1-SNAPSHOT</version><name>tx_sys</name><description>Demo project for Spring Boot</description><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!--導入jquery--><dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.3.1</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.1</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.0.9</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>net.sourceforge.nekohtml</groupId><artifactId>nekohtml</artifactId><version>1.9.22</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

2.thymeleaf模塊處理的配置類

package cn.tx.springboot.srcConfig;import cn.tx.springboot.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.ArrayList;
import java.util.List;/*** Spring MVC 配置類* 用于配置視圖控制器和攔截器*/
@Configuration
public class TxMvcConfig implements WebMvcConfigurer {/*** 添加視圖控制器* 用于直接將請求映射到視圖頁面,而不需要通過Controller類處理** @param registry 視圖控制器注冊器*/@Overridepublic void addViewControllers(ViewControllerRegistry registry) {// 將 /index 請求映射到 index 視圖頁面registry.addViewController("/index").setViewName("index");// 將 /menu 請求映射到 menu 視圖頁面registry.addViewController("/menu").setViewName("menu");// 將 /header 請求映射到 header 視圖頁面registry.addViewController("/header").setViewName("header");// 將 /login 請求映射到 login 視圖頁面registry.addViewController("/login").setViewName("login");// 將 /add 請求映射到 add 視圖頁面registry.addViewController("/add").setViewName("add");}/*** 添加攔截器* 配置一個登錄攔截器,用于攔截請求并執行登錄驗證邏輯** @param registry 攔截器注冊器*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 創建一個排除路徑的列表List<String> excludePatterns = new ArrayList<>();// 添加不需要攔截的路徑excludePatterns.add("/css/**");       // 排除所有以 /css/ 開頭的靜態資源路徑excludePatterns.add("/images/**");    // 排除所有以 /images/ 開頭的靜態資源路徑excludePatterns.add("/webjars/**");   // 排除所有以 /webjars/ 開頭的路徑excludePatterns.add("/login");        // 排除登錄頁面路徑excludePatterns.add("/toLogin");      // 排除跳轉到登錄頁面的路徑// 注冊登錄攔截器// 攔截所有請求路徑,但排除上述定義的路徑registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**")       // 攔截所有路徑.excludePathPatterns(excludePatterns); // 排除指定路徑}
}

這段代碼中使用了addViewController方法,它是ViewControllerRegistry接口提供的一個方法,用于將請求路徑映射到視圖名稱(這么用主要是因為可以在一個方法中實現多條路徑的映射)。具體語法如下:

registry.addViewController("/path").setViewName("viewName");

3.application配置文件

?接著在配置文件配置好鏈接數據庫的信息:

spring:datasource:username: rootpassword: 2020url: jdbc:mysql://localhost:3306/boot_demo?serverTimezone=GMT%2B8driver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSourceinitialSize: 5minIdle: 5maxActive: 20maxWait: 60000timeBetweenEvictionRunsMillis: 60000minEvictableIdleTimeMillis: 300000validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsepoolPreparedStatements: truefilters: stat,wall,log4jmaxPoolPreparedStatementPerConnectionSize: 20useGlobalDataSourceStat: trueconnectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500mvc:format:date: yyyy-MM-dd

這里面的配置項解析參見:SpringBoot 第三課(Ⅰ) 數據層開發-CSDN博客

除此之外,這里額外注意一點:

注意框起來的.cj.

在配置驅動時會遇見這個問題,有的加cj,有的不加cj,但是在某些時刻好像都是正確的,這就涉及到一些版本問題了:

MySQL現在三個版本:5.6(低版本);5.7(低版本);8.0(高版本)

但是能不能用cj,取決于jar包,并不是MySQL的版本決定的。

如果你需要使用 com.mysql.cj.jdbc.Driver,那么你需要引入 MySQL Connector/J 8.x 的依賴;同理如果是引入5.x的依賴,那么在配置文件這里就不用加cj。

4.配置(在啟動類中)

可以選擇加一個config包,里面寫配置類;也可以寫在springboot的項目啟動類中,在這里我采用將配置寫進啟動類中(因為我這個演示的項目邏輯比較簡單,一般情況下不建議這么做):

package cn.tx.springboot;import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;@MapperScan("cn.tx.springboot.dao")  //在驅動類標注好mapper的文件包,這樣就不用在每個dao接口文件中標注@Mapper了
@SpringBootApplication
public class TxSysApplication {public static void main(String[] args) {SpringApplication.run(TxSysApplication.class, args);}@ConfigurationProperties(prefix = "spring.datasource")@Beanpublic DruidDataSource getDruidDataSource(){return new DruidDataSource();}@Beanpublic ServletRegistrationBean statViewServlet(){ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(),"/druid/*");Map<String,String> initParams = new HashMap<>();initParams.put("loginUsername","root");initParams.put("loginPassword","root");initParams.put("allow","");//默認就是允許所有訪問initParams.put("deny","192.168.15.21");bean.setInitParameters(initParams);return bean;}//2、配置一個web監控的filter@Beanpublic FilterRegistrationBean webStatFilter(){FilterRegistrationBean bean;bean = new FilterRegistrationBean();bean.setFilter(new WebStatFilter());Map<String,String> initParams = new HashMap<>();initParams.put("exclusions","*.js,*.css,/druid/*");bean.setInitParameters(initParams);bean.setUrlPatterns(Arrays.asList("/*"));return bean;}@Beanpublic ConfigurationCustomizer getCustomizer(){return new ConfigurationCustomizer() {@Overridepublic void customize(org.apache.ibatis.session.Configuration configuration) {configuration.setMapUnderscoreToCamelCase(true);}};}
}

5.編寫數據層

①編寫實體類

package cn.tx.springboot.model;import java.util.Date;public class TxPerson {private int pid;private String username;private String password;private String pAddr;private String pname;private int gender;private Date birth;public TxPerson() {}public TxPerson(int pid, String username, String password, String addr, int gender, Date birth) {this.pid = pid;this.username = username;this.password = password;this.pAddr = pAddr;this.gender = gender;this.birth = birth;}public int getPid() {return pid;}public void setPid(int pid) {this.pid = pid;}public String getPname() {return pname;}public void setPname(String pname) {this.pname = pname;}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 getpAddr() {return pAddr;}public void setpAddr(String pAddr) {this.pAddr = pAddr;}public int getGender() {return gender;}public void setGender(int gender) {this.gender = gender;}public Date getBirth() {return birth;}public void setBirth(Date birth) {this.birth = birth;}@Overridepublic String toString() {return "TxPerson{" +"pid=" + pid +", username='" + username + '\'' +", password='" + password + '\'' +", pAddr='" + pAddr + '\'' +", pname='" + pname + '\'' +", gender=" + gender +", birth=" + birth +'}';}
}

②編寫dao層

這里選用SQL全注解的形式編寫dao接口文件:

package cn.tx.springboot.dao;import cn.tx.springboot.model.TxPerson;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;import java.util.List;
import java.util.Map;//@Mapper
/*** IDEA在注入處報錯(報紅),因為找不到注入的對象,因為類是動態創建的,但是程序可以正確的執行。* 為了避免報錯,可以在被注入dao接口上添加 @Repository 注解* */
@Repositorypublic interface PersonDao {@Select("select * from txperson")public List<TxPerson> select();@Select("select * from txperson where pid=#{pid}")public TxPerson getPersonById(int pid);@Update("update txperson set " +"username=#{username}," +"password=#{password}," +"pname=#{pname}," +"p_addr=#{pAddr}," +"gender=#{gender}," +"birth=#{birth} " +"where pid=#{pid}")public void updatePerson(TxPerson txPerson);@Options(useGeneratedKeys = true,keyProperty = "pid")@Insert("insert into txperson(pid, username,password,pname, p_addr,gender, birth)" +" values(#{pid}, #{username},#{password},#{pname}, #{pAddr},#{gender}, #{birth})")public void insert(TxPerson P);@Delete("delete from txperson where pid=#{pid}")public int delete(int pid);@Select("select * from txperson where username=#{username} and password=#{password}")public TxPerson getPersonUsepass(Map map);
}

可以看見在這個文件中,我將@Mapper注釋掉了,但是項目啟動后仍舊能夠正常運行起來,這是因為我在啟動類中標注了掃描路徑。

掃描路徑配置一覽

注:其實可以發現,這么編寫相較于Spring框架的編寫格式來說,省去了編寫Mapper.xml文件(因為將sql語句直接賦予給dao接口了),這么編寫大大節省的代碼量。

但是這么寫還是不夠精簡,后面為了方便項目開發,將引進MyBatisPlus技術,實現省略簡單SQL語句的編寫。

③編寫service層

接口
package cn.tx.springboot.service;import cn.tx.springboot.model.TxPerson;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.List;
import java.util.Map;@Transactional
public interface PersonService {public List<TxPerson> select();//修改首先通過id獲取要修改的數據public TxPerson getPersonById(int pid);//在通過修改方法修改public void  updatePerson(TxPerson txPerson);public void insert(TxPerson P);public int delete(int pid);public TxPerson getPersonUsepass(Map map);
}
?實現類

在service層的實現類中,一個方法中甚至可以調用多個dao的接口方法來實現一個業務邏輯方法(當然我這里展示的邏輯都比較簡單)

package cn.tx.springboot.service.impl;import cn.tx.springboot.dao.PersonDao;
import cn.tx.springboot.model.TxPerson;
import cn.tx.springboot.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;
import java.util.Map;@Service
public class PersonServiceImpl implements PersonService {@Autowiredprivate PersonDao personDao;@Overridepublic List<TxPerson> select() {List<TxPerson> list = personDao.select();return list;}@Overridepublic TxPerson getPersonById(int pid) {return personDao.getPersonById(pid);}@Overridepublic void updatePerson(TxPerson txPerson) {personDao.updatePerson(txPerson);}@Overridepublic void insert(TxPerson P) {personDao.insert(P);}@Overridepublic int delete(int pid) {return personDao.delete(pid);}@Overridepublic TxPerson getPersonUsepass(Map map) {TxPerson txPerson = personDao.getPersonUsepass(map);return txPerson;}
}
注意

controller層要注入service層(當然service的實現類注入dao“接口”同理;---@Autowired是進行注入的注釋)

但是顯而易見接口是不能被注入的,這里被注入的其實是實現這個接口的實體類

注入(圖Ⅰ)
補充(注入的3個注解)

提到這里就不得不多說一嘴有關實現注入的3個注解:

1.@AutoWired(類型注入)

什么叫類型注入?顧名思義,就是只用填寫類型,不用明確指出名字。前面已經提了,接口是不能被注入的,本質上注入的都是實現類。

Ⅰ圖中我這么直接寫是可以的,這是因為我的實現類層中只有一個實現類(參見圖Ⅱ)

圖Ⅱ

一旦我在impl中再創建一個實現PersonService接口的實現類,圖Ⅰ中的部分就將報錯,這是因為同類型(即同樣是實現PersonService接口的情況)下,有兩個實現類了,導致@AutoWired注解注入混亂,因此報錯。

2.@Qualifier(名稱注入)

這個就很容易理解了,在使用這個注解時表明要注入的實體類的名稱,而不是只標注它們實現接口的名稱這么泛泛。

上面這兩種注入方式(@AutoWired和@Qualifier)都是由Spring框架提供的,其中@AutoWired用到最多。

3.@Qualifier

可以按照名稱再按照類型,并且是Jdk封裝的,利用反射機制(不建議使用這個注解,主要還是上面那兩種居多。)

?④編寫controller層

在編寫controller之前,先將前端頁面信息展示:

首先目錄一共有這么幾個頁面:

前端信息直接給
前端頁面
1.add.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
body {font-family: Arial, Helvetica, sans-serif; font-size:12px; text-align:center;}
a { text-decoration: none;}
#all {widht: 100%; text-align:center; margin:auto;}
main {width: 96%; line-height: 1.8; margin:auto; border:1px #ccc dashed; text-align: left; text-indent: 2em;}
.mt{width: 1000px;border:1px solid #aca7a7 ;border-collapse: collapse;
}
.mt td{border: 1px solid #aca7a7;
}</style>
</head><body>
<div id="all"><form th:action="@{/insert}" method="post"><table class="mt"><tr><td>用戶名</td><td><input type="text" name="username"/></td><td>密碼</td><td><input type="text" name="password"/></td><td>姓名</td><td><input type="text" name="pname"/></td><td>地址</td><td><input type="text" name="pAddr"/></td><td>性別</td><td><select name="gender"><option value="1">男</option><option value="2">女</option></select></td><td>生日</td><td><input type="text" name="birth"/></td><td><input type="submit" value="提交"/></td></tr></table></form>
</div>
</body>
</html>
2.header.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Admin Header</title><link href="css/header.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" language="javascript" src="js/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
var oplist = new Array('about', 'user', 'news', 'mars', 'jielong', 'box', 'school', 'config', 'other');
$(document).ready(function() {$('#nav').find("a").click(function() {var id = $(this).attr('id');$.each(oplist, function(i, n) {$('#'+n).attr('class', 'inactive');});$(this).parents("li").attr('class', 'active');});
});
</script>
</head><body>
<div id="all"><div id="banner"><h1>Springboot實訓</h1></div><div id="nav"><ul><li class="inactive" id="other"><a href="menu.html" target="menu">管理操作</a></li><li class="inactive" id="about"><a href="menu.html" target="menu">管理操作</a></li><li class="inactive" id="user"><a href="menu.html" target="menu">管理操作</a></li><li class="inactive" id="news"><a href="menu.html" target="menu">管理操作</a></li><li class="inactive" id="mars"><a href="menu.html" target="menu">管理操作</a></li><li class="inactive" id="jielong"><a href="menu.html" target="menu">管理操作</a></li><li class="inactive" id="box"><a href="menu.html" target="menu">管理操作</a></li><li class="inactive" id="school"><a href="menu.html" target="menu">火柴學堂</a></li><li class="active" id="config"><a href="menu.html" target="menu">站點設置</a></li></ul></div><div id="main"><div id="welcome"><span th:if="${session.user != null}" th:text="${session.user.username}+'歡迎你回來!'"></span><a target="_top" th:if="${session.user == null}"  th:href="@{/login}">請登錄</a><img src="images/clock.gif" /> 學習是最好的投資</div><div id="adminop"><ul><li><a href="#">站點首頁</a></li><li><a href="javascript:parent.location.reload();">管理首頁</a></li><li><a href="javascript:parent.location.reload();">退出管理</a></li><li><a href="#">站點首頁</a></li></ul></div></div>
</div>
</body>
</html>
3.index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>青城博雅教育首頁</title>
</head><frameset cols="*" rows="136, *" id="frame_main"  border="0"><frame th:src="@{/header}" noresize="noresize" name="header"><frameset cols="240, *"><frame th:src="@{/menu}" name="menu" /><frame th:src="@{/main}" name="main"></frameset>
</frameset><noframes><body>
</body>
</noframes></html>
4.login.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>用戶登錄</title>
<link href="css/login.css" rel="stylesheet" type="text/css" /><script th:src="@{/webjars/jquery/3.3.1/jquery.js}"></script><script>function login() {$("form").submit();}</script>
</head>
<body><div id="login"><div id="top"><div id="top_left"><img src="images/login_03.gif" /></div><div id="top_center"></div></div><form th:action="@{/toLogin}" method="post"><div id="center"><div id="center_left"></div><div id="center_middle"><div style="text-align: center; color: red" th:text="${tip}"></div><div id="user">用 戶<input type="text" name="username" /></div><div id="password">密   碼<input type="password" name="password" /></div><div id="btn"><a href="#" onclick="login()">登錄</a><a href="#">清空</a></div></div><div id="center_right"></div></div></form><div id="down"><div id="down_left"><div id="inf"><span class="inf_text">版本信息</span><span class="copyright">v2.0</span></div></div><div id="down_center"></div></div></div>
</body>
</html>
5.main.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
body {font-family: Arial, Helvetica, sans-serif; font-size:12px; text-align:center;}
a { text-decoration: none;}
#all {widht: 100%; text-align:center; margin:auto;}
main {width: 96%; line-height: 1.8; margin:auto; border:1px #ccc dashed; text-align: left; text-indent: 2em;}
.mt{width: 1000px;border:1px solid #aca7a7 ;border-collapse: collapse;
}
.mt td{border: 1px solid #aca7a7;
}</style>
</head><body>
<div id="all"><div><a th:href="@{/add}">添加</a></div><table class="mt"><tr><td>用戶名</td><td>姓名</td><td>地址</td><td>性別</td><td>生日</td><td>操作</td></tr><tr th:each="p:${list}"><td th:text="${p.username}"></td><td th:text="${p.pname}"></td><td th:text="${p.pAddr}"></td><td th:text="${p.gender==1}?'男':'女'"></td><td th:text="${#calendars.format(p.birth,'yyyy-MM-dd')}"></td><td><a th:href="@{/getPerson(pid=${p.pid})}">修改</a><a th:href="@{/delete(pid=${p.pid})}" >刪除</a></td></tr></table></div>
</body>
</html>
6.menu.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>無標題文檔</title><link href="css/menu.css" rel="stylesheet" type="text/css" />
</head><body>
<div id="all"><div id="menu"><ul><li><img src="images/li.jpg" />&nbsp;&nbsp;&nbsp; <a href="/main" target="main">員工管理</a></li><li><img src="images/li.jpg" />&nbsp;&nbsp;&nbsp; <a href="" target="main">部門管理</a></li><li><img src="images/li.jpg" />&nbsp;&nbsp;&nbsp; <a href="" target="main">績效管理</a></li><li><img src="images/li.jpg" />&nbsp;&nbsp;&nbsp; <a href="" target="main">財務管理</a></li></ul></div>
</div>
</body>
</html>
7.update.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
body {font-family: Arial, Helvetica, sans-serif; font-size:12px; text-align:center;}
a { text-decoration: none;}
#all {widht: 100%; text-align:center; margin:auto;}
main {width: 96%; line-height: 1.8; margin:auto; border:1px #ccc dashed; text-align: left; text-indent: 2em;}
.mt{width: 1000px;border:1px solid #aca7a7 ;border-collapse: collapse;
}
.mt td{border: 1px solid #aca7a7;
}</style>
</head><body>
<div id="all"><form th:action="@{/updatePerson}" method="post"><input type="hidden" name="pid" th:value="${p.pid}"/><table class="mt"><tr><td>用戶名</td><td><input type="text" name="username"  th:value="${p.username}"/></td><td>密碼</td><td><input type="text" name="password"  th:value="${p.password}"/></td><td>姓名</td><td><input type="text" name="pname"  th:value="${p.pname}"/></td><td>地址</td><td><input type="text" name="pAddr"  th:value="${p.pAddr}"/></td><td>性別</td><td><select name="gender"><option value="1" th:selected="${p.gender}==1">男</option><option value="2" th:selected="${p.gender}==2">女</option></select></td><td>生日</td><td><input type="text" name="birth" th:value="${#calendars.format(p.birth,'yyy-MM-dd')}"/></td><td><input type="submit" value="提交"/></td></tr></table></form>
</div>
</body>
</html>
css
1.header.css
body {background: #686868; font-family:Arial, Helvetica, sans-serif; font-size:12px; margin:0px; margin-bottom:2px;border-bottom: 1px #ccc solid;}
h1 {color: #FFF;}
a {color: #FFF; text-decoration: none;/*防止濾鏡下鏈接失效*/position:relative;}
ul { list-style:none;}
#all {width: 100%;}
#banner {margin-top: 8px; margin-left: 32px;}
#main {width: 100%; margin-bottom: 2px; background:#eeeeee; margin-left: 0px; margin-right:0px; height: 30px; color: #000; line-height: 2.4;overflow: auto;}
#main a {color:#000;}
#welcome { float:left; width: 40%; font-weight: 800; padding-left: 8px; position:relative;}
#adminop { float:left; width: 59%; position:relative; text-align:right; line-height:1; *line-height:2.2;}
#adminop ul li {float: right; width: 80px;}
#nav {width: 100%; clear: both;}
#nav ul li {float: right; width:82px; height:25px; line-height: 2.1; text-align: center;}
.inactive { background-image/**/:url(../images/admin/nav_bg_inactive2.png) !important;background: none; margin-left: 2px; margin-right:2px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=images/admin/nav_bg_inactive2.png);}
.inactive a {color: #000;}
.active {background:url(../images/admin/nav_bg_active2.png) !important;background: none; margin-left: 2px; margin-right:2px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=images/admin/nav_bg_active2.png);}
.active a {color:#fff;}
.blankgray {background:#bbb; height:2px; width:100%; margin:0; padding:0; clear:both; font-size:2px;}
2.login.css
body{margin:0; padding:0; font-size:9pt;}
#login{margin:auto; width:975px; height:368px; margin-top:120px;}
#top_left{width:691px; height:89px; float:left;}
#top_left img {margin-left:33px;}
#top_center{width:248px; height:89px; background:url(../images/03.jpg); float:left;}#center_left{width:691px; height:190px; background:url(../images/04.jpg); float:left;}
#center_middle{width:248px; height:220px; float:left; background:url(../images/login_13.gif) repeat-y;}
#center_right{width:36px; height:190px; float:right; background:url(../images/login_11.gif);}#down_left{width:691px; height:89px; float:left; margin-top:15px;}
#down_center{width:248px; height:89px; background:url(../images/login_16.gif); float:left;}
#inf{width:691px; height:38px; background:url(../images/login_18.gif) no-repeat; }
.inf_text{display:block; width:100px; height:20px; font-size:16px; font-weight:bolder; color:#fff; margin-left:17px; margin-top:12px; float:left;}
.copyright{display:block; float:left; margin-left:17px; margin-top:15px;}#user{ margin-left:40px; margin-top:45px; height:25px;}
#password{margin-left:40px; margin-top:25px; height:25px;}
input{width:120px; height:18px; border:solid 1px #aca7a7; font-size:9pt;}
#btn{margin-left:30px; margin-top:40px;height:25px; margin-right:28px; text-align:center;}
#btn a{display:block; line-height:25px; background: url(../images/bt_bg.gif); border: solid 1px #b6b6b6; width:65px; float:left; margin-left:15px; text-decoration:none; color:#000;}
3.menu.css
html, body {height:100%;overflow:hidden;} /*為兼容ie7,ff*/
body {font-family:Arial, Helvetica, sans-serif; font-size:12px; margin:0px; text-align:center; border-right:1px #ccc solid;}
a {color: #000; text-decoration: none;}
#menu img {_margin-top: 12px;}/*沒辦法,ie6對list-style-image支持不好*/
#all {width: 100%;height:100%;}
#menu {width: 96%;}
#menu ul {padding:0; margin: 0; list-style: none;}
#menu ul li {background-image:url(../images/match/public/images/menu_bg.gif); background-repeat: repeat-x; background-position:center; height: 32px;;margin-top: 2px; margin-bottom: 2px; border:1px #ccc solid; line-height: 2.8;}
4.style.css
@CHARSET "UTF-8";
.pro{height: 8px;background-color: #4C4C4C;width: 500px;cursor: pointer;}.playball{height: 8px;width: 8px;background-color: orange;position: relative;}.time{width: 500px;height: 20px;border: 1px solid black;
}
?controller代碼
package cn.tx.springboot.controller;import cn.tx.springboot.model.TxPerson;
import cn.tx.springboot.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.Mapping;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@Controller
//@Repository
public class TxPersonController {@AutowiredPersonService personService;@RequestMapping("/main")public String  main(Model model){List<TxPerson> list = personService.select();model.addAttribute("list",list);return "main";}@RequestMapping("/insert")public String  insert(TxPerson person){personService.insert(person);return "redirect:main";}@RequestMapping("/getPerson")public String  getPerson(int pid,Model model){TxPerson person = personService.getPersonById(pid);model.addAttribute("p",person);return "update";}@RequestMapping("/updatePerson")public String  update(TxPerson person){personService.updatePerson(person);return "redirect:main";}@RequestMapping("/delete")public String  delete(int pid){personService.delete(pid);return "redirect:main";}@RequestMapping("/toLogin")public String  login(String username, String password, HttpSession session, Model model){Map<String, String> map = new HashMap<String, String>();map.put("username", username);map.put("password", password);TxPerson txPerson = personService.getPersonUsepass(map);model.addAttribute("p",txPerson);if (txPerson!=null){session.setAttribute("user",txPerson);return "index";}else {model.addAttribute("tip","用戶名或密碼錯誤!");return "login";}}
}

⑤編寫攔截類

package cn.tx.springboot.interceptor;import cn.tx.springboot.model.TxPerson;
import org.springframework.web.context.request.WebRequestInterceptor;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {TxPerson user = (TxPerson) request.getSession().getAttribute("user");if(user!=null){return true;}response.sendRedirect(request.getContextPath()+"/login");return false;}
}

三、測試

實現上面的過程后就可以訪問頁面了(隨便訪問一個controller中對應的路徑即可,因為在配置中配置了跳轉路徑,所以不登錄直接訪問,訪問任何頁面都會被跳轉到login.html頁面)

按照自己數據庫中的信息自行登錄即可

注意:?我沒有提供項目中的圖片信息,所以打開可能并不是這個頁面(圖片自行下載微調前端即可)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/73067.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/73067.shtml
英文地址,請注明出處:http://en.pswp.cn/web/73067.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

高性能網絡SIG雙月動態:加速 SMC eBPF 透明替換特性上游化進程,并與上游深度研討新特性

01、整體進展 本次雙月報總結了 SIG 在 1 月和 2 月的工作進展&#xff0c;工作聚焦在 ANCK CVE 和穩定性問題修復&#xff0c;以及上游 SMC eBPF 透明替換特性推進和多個話題討論上。 本月關鍵進展&#xff1a; 1. 推進 SMC eBPF 透明替換特性上游化&#xff0c;更新至 V7&…

某視頻的解密下載

下面講一下怎么爬取視頻&#xff0c;這個還是比小白的稍微有一點繞的 首先打開網址&#xff1a;aHR0cDovL3d3dy5wZWFydmlkZW8uY29tL3BvcHVsYXJfNA 首頁 看一下&#xff1a; 有一個標題和一個href&#xff0c;href只是一個片段&#xff0c;待會肯定要拼接&#xff0c; 先找一…

C++繼承機制:從基礎到避坑詳細解說

目錄 1.繼承的概念及定義 1.1繼承的概念 1.2 繼承定義 1.2.1定義格式 1.2.2繼承關系和訪問限定符 1.2.3繼承基類成員訪問方式的變化 總結&#xff1a; 2.基類和派生類對象賦值轉換 3.繼承中的作用域 4.派生類的默認成員函數 ?編輯 默認構造與傳參構造 拷貝構造&am…

測試基礎入門

文章目錄 軟件測試基礎1.1軟件測試概述什么是軟件測試什么是軟件需求說明書軟件測試的原則測試用例的設計測試用例設計的基本原則軟件測試分類軟件缺陷的定義 2.1軟件開發模型軟件開發模型概述大爆炸模型&#xff08;邊寫邊改&#xff09;軟件開發生命周期模型--螺旋模型軟件開…

022-spdlog

spdlog 以下是從原理到代碼實現的全方位spdlog技術調研結果&#xff0c;結合核心架構、優化策略和完整代碼示例&#xff1a; 一、核心架構設計原理 spdlog三級架構 &#xff08;圖示說明&#xff1a;spdlog采用三級結構實現日志系統解耦&#xff09; Registry管理中樞 全局…

STM32時鐘樹

時鐘樹 時鐘樹就是STM32中用來產生和配置時鐘&#xff0c;并且把配置好的時鐘發送到各個外設的系統&#xff0c;時鐘是所有外設運行的基礎&#xff0c;所以時鐘也是最先需要配置的東西&#xff0c;在程序中主函數之前還會執行一個SystemClock_Config()函數&#xff0c;這個函數…

【第22節】windows網絡編程模型(WSAAsyncSelect模型)

目錄 引言 一、WSAAsyncSelect模型概述 二、WSAAsyncSelect模型流程 2.1 自定義消息 2.2 創建窗口例程 2.3 初始化套接字 2.4 注冊網絡事件 2.5 綁定和監聽 2.6 消息循環 三、完整示例代碼 引言 在網絡編程的廣袤天地中&#xff0c;高效處理網絡事件是構建穩定應用的…

利用Dify編制用戶問題意圖識別和規范化回復

繼上一篇文章&#xff0c;成功完成Dify本地部署后&#xff0c;主要做了一些workflow和Agent的應用實現&#xff0c;整體感覺dify在工作流可視化編排方面非常好&#xff0c;即使部分功能無法實現&#xff0c;也可以通過代碼執行模塊或者自定義工具來實現&#xff08;后續再具體分…

雙核鎖步技術在汽車芯片軟錯誤防護中的應用詳解

摘要 本文深入探討了雙核鎖步技術在保障汽車芯片安全性中的應用。文章首先分析了國產車規芯片在高安全可靠領域面臨的軟錯誤難點及攻克方向&#xff0c;然后詳細介紹了雙核鎖步技術的基本原理及其在汽車芯片防軟錯誤的重要性。通過對比國內外多家廠商的芯片技術&#xff0c;分析…

Lustre 語言的 Rust 生成相關的工作

目前 Lustre V6 編譯器支持編譯生成的語言為C語言。但也注意到&#xff0c;以 Rust 語言為生成目標語言&#xff0c;也存在若干相關工作。 rustre&#xff08;elegaanz&#xff09; 該項工作為 Lustre v6 語言的解析器&#xff0c;使用 Rust 語言實現。生成 Lustre AST。 項…

Java 之「單調棧」:從入門到實戰

Java 單調棧&#xff1a;從入門到實戰 文章目錄 Java 單調棧&#xff1a;從入門到實戰引言什么是單調棧&#xff1f;單調遞增棧單調遞減棧 單調棧的應用場景Java 實現單調棧代碼示例&#xff1a;下一個更大元素代碼解析 單調棧的優勢實戰應用&#xff1a;股票價格跨度代碼示例代…

【Golang】defer與recover的組合使用

在Go語言中&#xff0c;defer和recover是兩個關鍵特性&#xff0c;通常結合使用以處理資源管理和異常恢復。以下是它們的核心應用場景及使用示例&#xff1a; 1. defer 的應用場景 defer用于延遲執行函數調用&#xff0c;確保在函數退出前執行特定操作。主要用途包括&#xff…

CSS 中flex - grow、flex - shrink和flex - basis屬性的含義及它們在彈性盒布局中的協同作用。

大白話CSS 中flex - grow、flex - shrink和flex - basis屬性的含義及它們在彈性盒布局中的協同作用。 在 CSS 的彈性盒布局&#xff08;Flexbox&#xff09;里&#xff0c;flex-grow、flex-shrink 和 flex-basis 這三個屬性對彈性元素的尺寸和伸縮性起著關鍵作用。下面為你詳細…

OpenGL ES ->乒乓緩沖,計算只用兩個幀緩沖對象(Frame Buffer Object)+疊加多個濾鏡作用后的Bitmap

乒乓緩沖核心思想 不使用乒乓緩沖&#xff0c;如果要每個濾鏡作用下的繪制內容&#xff0c;也就是這個濾鏡作用下的幀緩沖&#xff0c;需要創建一個Frame Buffer Object加上對應的Frame Buffer Object Texture使用乒乓緩沖&#xff0c;只用兩個Frame Buffer Object加上對應的F…

【HarmonyOS NEXT】關鍵資產存儲開發案例

在 iOS 開發中 Keychain 是一個非常安全的存儲系統&#xff0c;用于保存敏感信息&#xff0c;如密碼、證書、密鑰等。與文件系統不同&#xff0c;Keychain 提供了更高的安全性&#xff0c;因為它對數據進行了加密&#xff0c;并且只有經過授權的應用程序才能訪問存儲的數據。那…

ccfcsp1901線性分類器

//線性分類器 #include<iostream> using namespace std; int main(){int n,m;cin>>n>>m;int x[1000],y[1000];char z[1000];for(int i0;i<n;i){cin>>x[i]>>y[i];cin>>z[i];}int a[20],b[20],c[20];for(int i0;i<m;i){cin>>a[i…

Spring Boot 整合 OpenFeign 教程

精心整理了最新的面試資料和簡歷模板&#xff0c;有需要的可以自行獲取 點擊前往百度網盤獲取 點擊前往夸克網盤獲取 Spring Boot 整合 OpenFeign 教程 一、OpenFeign 簡介 OpenFeign 是 Netflix 開源的聲明式 HTTP 客戶端&#xff0c;通過接口和注解簡化服務間 HTTP 調用。…

APM 仿真遙控指南

地面站開發了一段時間了&#xff0c;由于沒有硬件&#xff0c;所以一直在 APM 模擬器中驗證。我們已經實現了 MAVLink 消息接收和解析&#xff0c;顯示無人機狀態&#xff0c;給無人機發送消息&#xff0c;實現一鍵起飛&#xff0c;飛往指定地點&#xff0c;降落&#xff0c;返…

C語言入門教程100講(4)輸入輸出

文章目錄 1. 什么是輸入輸出&#xff1f;2. 標準輸入輸出函數2.1 printf 函數2.2 scanf 函數 3. 格式化占位符4. 示例代碼代碼解析&#xff1a;輸出結果&#xff1a; 5. 常見問題問題 1&#xff1a;scanf 中的 & 是什么作用&#xff1f;問題 2&#xff1a;printf 和 scanf …

《信息系統安全》(第一次上機實驗報告)

實驗一 &#xff1a;網絡協議分析工具Wireshark 一 實驗目的 學習使用網絡協議分析工具Wireshark的方法&#xff0c;并用它來分析一些協議。 二實驗原理 TCP/IP協議族中網絡層、傳輸層、應用層相關重要協議原理。網絡協議分析工具Wireshark的工作原理和基本使用規則。 三 實…