Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
實(shí)際開發(fā)過程中,使用maven管理jar給我們開發(fā)帶來了很多便利,不需要自己一個(gè)一個(gè)的jar包下載了,只需要配置個(gè)pom配置文件就可以了,寫上對(duì)應(yīng)坐標(biāo)和倉庫地址就可以了。但是jar沖突沒問題沒有解決,有沖突的jar包maven不會(huì)給我們檢查出來還是會(huì)根據(jù)我們的配置進(jìn)行下載,等到編譯才會(huì)報(bào)錯(cuò),并且報(bào)錯(cuò)信息很晦澀,需要面向百度查一會(huì)可能才能定位出問題。
這時(shí)候我們迫切需要有個(gè)東東可以提前告訴我們我的工程里有內(nèi)奸,需要及時(shí)剔除,否則會(huì)影響軍心。
1、maven插件,通過參數(shù)指令傳給插件
2、工程里所有jar包沖突預(yù)警
3、工程中不能共存jar預(yù)警
4、自定義規(guī)則預(yù)警
3.1 詳細(xì)技術(shù)方案
1、maven插件開發(fā),繼承AbstractMojo,入口方法execute,命令參數(shù)可以通過注解方式傳入,例如:@Parameter(property="groupId"),邊亮可以獲取groupId對(duì)應(yīng)傳入的參數(shù)值。
2、獲取工程中所有的jar包及類:通過Maven獲取MavenProject,拿到工程后就可以拿到所有的jar及其所有依賴樹,把所有jar包放到一個(gè)大map中。
3、jar包沖突算法:
A、相同jar包版本沖突:通過自定義規(guī)則配置到屬性文件中,定義某jar的哪些版本水火不相容。規(guī)則示例:xxxgroupId:xxxArtifactId>5.1.8,那么程序則認(rèn)為這個(gè)坐標(biāo)的jar包大于我要發(fā)(5.1.8)時(shí)就是內(nèi)奸,需要除掉。
B、相同jar包版本沖突:倆jar包中有class個(gè)數(shù)不同或者個(gè)數(shù)相同但是MD5后結(jié)果不同或者倆jar包中有相同類大小不同這三種情況認(rèn)為此山不容倆jar包。具體代碼此處省略一萬行。
C、不相同jar包沖突:通過自定義規(guī)則配置到屬性文件中,定義某jar的某個(gè)版本和別的某jar包某個(gè)版本互看不順眼。規(guī)則示例:if 王寶強(qiáng)groupId:王寶強(qiáng)ArtifactId >=2.2.2 then 經(jīng)紀(jì)人groupId:經(jīng)紀(jì)人ArtifactId>3.3.3,此規(guī)則代表王寶強(qiáng)jar包版本222與經(jīng)紀(jì)人jar包版本333不能共存,否則會(huì)產(chǎn)生綠帽子,給出綠帽告警。
已知的會(huì)產(chǎn)生綠帽告警的有如下:
log4j-over-slf4j 和 slf4j-log4j12 不能共存。
jcl-over-slf4j 和 slf4j-jcl 不能共存。
jcl-over-slf4j 和 commons-logging 不能共存。
出處:https://www.slf4j.org/codes.html#version_mismatch。
部分核心代碼展示
完成SpringBoot打包獨(dú)立可執(zhí)行Web項(xiàng)目(2)
章通過名片管理系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn),講述如何使用SSM框架來實(shí)現(xiàn)一個(gè)Web應(yīng)用。通過本章的學(xué)習(xí),掌握SSM框架應(yīng)用開發(fā)的流程、方法以及技術(shù)
名片管理系統(tǒng)是針對(duì)注冊(cè)用戶使用的系統(tǒng)。系統(tǒng)提供的功能如下:
1.非注冊(cè)用戶可以注冊(cè)為注冊(cè)用戶。
2.成功注冊(cè)的用戶,可以登錄系統(tǒng)。
3.成功登錄的用戶,可以添加、修改、刪除以及瀏覽自己客戶的名片信息。
4.成功登錄的用戶,可以修改密碼
用戶登錄成功后,進(jìn)入管理主頁面(main.jsp)可以對(duì)自己的客戶名片進(jìn)行管理。系統(tǒng)模塊劃分,如圖4.1所示。
■ 圖4.1 名片管理系統(tǒng)
系統(tǒng)采用加載純Java數(shù)據(jù)庫驅(qū)動(dòng)程序的方式連接MySQL5.x數(shù)據(jù)庫。在MySQL5.x的數(shù)據(jù)庫ch4中,共創(chuàng)建兩張與系統(tǒng)相關(guān)的數(shù)據(jù)表:usertable和cardtable。
根據(jù)系統(tǒng)設(shè)計(jì)與分析,可以設(shè)計(jì)出如下數(shù)據(jù)結(jié)構(gòu):
1.用戶
包括ID、用戶名以及密碼,注冊(cè)用戶名唯一。
2.名片
包括ID、名稱、電話、郵箱、單位、職務(wù)、地址、Logo以及所屬用戶。其中,ID唯一,“所屬用戶”與“1.用戶”的用戶ID關(guān)聯(lián)。
根據(jù)以上數(shù)據(jù)結(jié)構(gòu),結(jié)合數(shù)據(jù)庫設(shè)計(jì)特點(diǎn),可畫出如圖4.2所示的數(shù)據(jù)庫概念結(jié)構(gòu)圖。
■ 圖4.2 數(shù)據(jù)庫概念結(jié)構(gòu)圖
其中,ID為正整數(shù),值是從1開始遞增的序列。
將數(shù)據(jù)庫概念結(jié)構(gòu)圖轉(zhuǎn)換為MySQL數(shù)據(jù)庫所支持的實(shí)際數(shù)據(jù)模型,即數(shù)據(jù)庫的邏輯結(jié)構(gòu)。
用戶信息表(usertable)的設(shè)計(jì),如表4.1所示。
■ 表4.1 用戶信息表
名片信息表(cardtable)的設(shè)計(jì),如表4.2所示。
■ 表4.2 名片信息表
為方便管理,在/WebContent/static目錄下存放與系統(tǒng)相關(guān)的靜態(tài)資源,如BootStrap相關(guān)的CSS與JS;在/WEB-INF/jsp目錄下存放與系統(tǒng)相關(guān)的JSP頁面。
在本系統(tǒng)中,與名片管理相關(guān)的功能包括添加、修改、刪除、查詢等,由控制器類CardController負(fù)責(zé)處理。由系統(tǒng)功能需求可知,用戶必須成功登錄才能管理自己的名片,所以,CardController處理添加、修改、刪除、查詢名片等功能前,需要進(jìn)行登錄權(quán)限驗(yàn)證。在CardController中,使用@ModelAttribute注解的方法進(jìn)行登錄權(quán)限驗(yàn)證。
在本系統(tǒng)中,與名片管理相關(guān)的功能包括添加、修改、刪除、查詢等,由控制器類CardController負(fù)責(zé)處理。由系統(tǒng)功能需求可知,用戶必須成功登錄才能管理自己的名片,所以,CardController處理添加、修改、刪除、查詢名片等功能前,需要進(jìn)行登錄權(quán)限驗(yàn)證。在CardController中,使用@ModelAttribute注解的方法進(jìn)行登錄權(quán)限驗(yàn)證。
Dao層是數(shù)據(jù)訪問層,即@Repository注解的數(shù)據(jù)操作接口(接口中的方法與SQL映射文件中元素的id對(duì)應(yīng)),與名片管理相關(guān)的數(shù)據(jù)訪問層為CardMapper。
SQL映射文件的namespace屬性與數(shù)據(jù)操作接口對(duì)應(yīng)。與名片管理功能相關(guān)的SQL映射文件是CardMapper.xml(位于dao包中)
首先,用戶登錄成功后,進(jìn)入名片管理系統(tǒng)的主頁面。然后,用戶在名片管理主頁面單擊“添加名片”超鏈接打開添加名片頁面。最后,用戶輸入客戶名片的姓名、電話、E-Mail、單位、職務(wù)、地址、Logo后,單擊“添加”按鈕實(shí)現(xiàn)添加。如果成功,則跳轉(zhuǎn)到名片管理主頁面;如果失敗,則回到添加名片頁面。
addCard.jsp頁面實(shí)現(xiàn)添加名片信息的輸入界面,如圖4.3所示。
■ 圖4.3 添加名片頁面
單擊圖4.3中“添加”按鈕,將添加請(qǐng)求通過“card/addCard?act=add”提交給控制器類CardController(4.5.2節(jié))的addCard方法進(jìn)行添加功能處理。添加成功跳轉(zhuǎn)到名片管理主頁面;添加失敗回到添加名片頁面。
用戶登錄成功后,進(jìn)入名片管理系統(tǒng)的主頁面(main.jsp),運(yùn)行效果如圖4.4所示。
■ 圖4.4 名片管理主頁面
在主頁面中單擊“詳情”超鏈接,打開名片詳細(xì)信息頁面detail.jsp。“詳情”超鏈接的目標(biāo)地址是個(gè)url請(qǐng)求。該請(qǐng)求路徑為“card/detail?id=${card.id}&act=detail”。根據(jù)請(qǐng)求路徑找到對(duì)應(yīng)控制器類CardController的detail方法處理查詢一個(gè)名片功能。根據(jù)動(dòng)作類型(“修改”以及“詳情”),將查詢結(jié)果轉(zhuǎn)發(fā)到不同視圖。名片詳細(xì)信息頁面cardDetail.jsp運(yùn)行效果如圖4.5所示。
■ 圖4.5 名片詳情
單擊名片管理主頁面中“修改”超鏈接,打開修改名片信息頁面updateCard.jsp。“修改”超鏈接的目標(biāo)地址是url請(qǐng)求card/detail?id=${card.id}&act=update。找到對(duì)應(yīng)控制器類CardController的方法detail,在該方法中,根據(jù)動(dòng)作類型,將查詢結(jié)果轉(zhuǎn)發(fā)給updateCard.jsp頁面顯示。
輸入要修改的信息后,單擊“修改”按鈕,將名片信息提交給控制器類,找到對(duì)應(yīng)控制器類CardController的方法addCard,在addCard方法中根據(jù)動(dòng)作類型,執(zhí)行修改的業(yè)務(wù)處理。修改成功,進(jìn)入名片管理主頁面。修改失敗,回到updateCard.jsp頁面。
updateCard.jsp頁面的運(yùn)行效果如圖4.6所示。
■ 圖4.6 updateCard.jsp頁面
在名片管理主頁面中,單擊“刪除”超鏈接,將要?jiǎng)h除名片的ID通過Ajax提交給控制器類。找到對(duì)應(yīng)控制器類CardController的方法delete,在該方法中,執(zhí)行刪除的業(yè)務(wù)處理。刪除成功后,進(jìn)入管理主頁面
在本系統(tǒng)中,與用戶相關(guān)的功能包括用戶注冊(cè)、用戶登錄以及用戶檢查等,由控制器類UserController負(fù)責(zé)處理。
與用戶相關(guān)的Service接口和實(shí)現(xiàn)類分別為UserService和UserServiceImpl。控制器獲取一個(gè)請(qǐng)求后,需要調(diào)用Service層中業(yè)務(wù)處理方法,在Service層中需要調(diào)用Dao層。所以,Service層是控制器層和Dao層的橋梁。UserService接口的代碼略。
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserMapper userMapper;
/***
* 檢查用戶名是否可用
*/
@Override
public String checkUname(MyUser myUser) {
List<MyUserTable> userList=userMapper.selectByUname(myUser);
if(userList.size() > 0)
return "no";
return "ok";
}
/**
* 實(shí)現(xiàn)注冊(cè)功能
*/
@Override
public String register(MyUser myUser) {
//將明文變成密文
myUser.setUpwd(MD5Util.MD5(myUser.getUpwd()));
if(userMapper.register(myUser) > 0)
return "login";
return "register";
}
/**
* 實(shí)現(xiàn)登錄功能
*/
@Override
public String login(MyUser myUser, Model model, HttpSession session) {
//ValidateCodeController中的rand
String code=(String)session.getAttribute("rand");
if(!code.equalsIgnoreCase(myUser.getCode())) {
model.addAttribute("errorMessage", "驗(yàn)證碼錯(cuò)誤!");
return "login";
}else {
//將明文變成密文
myUser.setUpwd(MD5Util.MD5(myUser.getUpwd()));
List<MyUserTable> list=userMapper.login(myUser);
if(list.size() > 0){
session.setAttribute("userLogin", list.get(0));
return "redirect:/card/selectAllCardsByPage?currentPage=1";
}else {
model.addAttribute("errorMessage", "用戶名或密碼錯(cuò)誤!");
return "login";
}
}
}
}
Dao層是數(shù)據(jù)訪問層,即@Repository注解的數(shù)據(jù)操作接口(接口中的方法與SQL映射文件中元素的id對(duì)應(yīng)),與用戶相關(guān)的數(shù)據(jù)訪問層為UserMapper。
SQL映射文件的namespace屬性與數(shù)據(jù)操作接口對(duì)應(yīng)。與用戶相關(guān)的SQL映射文件是UserMapper.xml(位于dao包中),具體代碼如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.UserMapper">
<select id="selectByUname" resultType="MyUserTable" parameterType="MyUser">
select * from usertable where uname=#{uname}
</select>
<insert id="register" parameterType="MyUser">
insert into usertable (id,uname,upwd) values(null,#{uname},#{upwd})
</insert>
<select id="login" parameterType="MyUser" resultType="MyUserTable">
select * from usertable where uname=#{uname} and upwd=#{upwd}
</select>
</mapper>
在登錄頁面login.jsp,單擊“注冊(cè)”鏈接,打開注冊(cè)頁面register.jsp,效果如圖4.7所示。
■ 圖4.7 注冊(cè)頁面
在圖4.7所示的注冊(cè)頁面中,輸入“姓名”后,系統(tǒng)將通過Ajax提交“user/checkUname” 請(qǐng)求檢測(cè)“姓名”是否可用。輸入合法的用戶信息后,單擊“注冊(cè)”按鈕,實(shí)現(xiàn)注冊(cè)功能。
在瀏覽器中,通過地址http://localhost:8080/ch4打開登錄頁面login.jsp,效果如圖4.8所示。
■ 圖4.8 登錄界面
用戶輸入姓名、密碼和驗(yàn)證碼后,系統(tǒng)將對(duì)姓名、密碼和驗(yàn)證碼進(jìn)行驗(yàn)證。如果姓名、密碼和驗(yàn)證碼同時(shí)正確,則登錄成功,將用戶信息保存到session對(duì)象,并進(jìn)入系統(tǒng)管理主頁面(main.jsp);如果輸入有誤,則提示錯(cuò)誤。
單擊名片管理主頁面中的“修改密碼”菜單,打開密碼修改頁面updatePwd.jsp。密碼修好頁面效果如圖4.9所示。
■ 圖4.9 密碼修改頁面
在圖4.9中輸入“新密碼”后,單擊“修改”按鈕,將請(qǐng)求通過“card/updatePwd”提交給控制器類。根據(jù)請(qǐng)求路徑找到對(duì)應(yīng)控制器類CardController的updatePwd方法處理密碼修改請(qǐng)求。這里找控制器類CardController處理密碼修改,是因?yàn)橛脩舯仨毜卿洺晒蟛拍苄薷拿艽a。
在名片管理主頁面中,單擊“安全退出”菜單,將返回登錄頁面。“安全退出”超鏈接的目標(biāo)地址是一個(gè)請(qǐng)求card/loginOut,找到控制器類CardController的對(duì)應(yīng)處理方法loginOut。這里找控制器類CardController處理安全退出,是因?yàn)橛脩舯仨毜卿洺晒蟛拍馨踩顺觥?/span>
本章講述了名片管理系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)。通過我們的學(xué)習(xí),不僅掌握SSM框架整合開發(fā)的流程、方法和技術(shù),還應(yīng)該熟悉名片管理的業(yè)務(wù)需求、設(shè)計(jì)以及實(shí)現(xiàn)。
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。