Struts2第四天 html
昨天:前端
Intercepters(配置攔截器),intercepter(自定義攔截器),配置自定義攔截器棧,把自定義的攔截器和默認的攔截器棧,放入自定義攔截器棧 java
覆蓋默認的攔截器棧 mysql
取值:[0].top s:property s:property value="key"(從root棧棧頂開始搜索,直到map棧,搜索到的第一個key返回),s:property value="#key":直接從map棧獲取數據。 jquery
今天的安排:web
目標:ajax
jsp-smartupload 組件 Servlet3.0 之後 API內置文件上傳API COS 文件上傳組件 |
Struts2 內部文件上傳,默認採用 apache commons-fileupload
Struts2 默認導入文件上傳jar包
文件上傳不少代碼都是同樣的,那麼還須要咱們本身去寫嗎,有一個攔截器已經幫咱們封裝了大部分代碼
defaultStack 默認攔截器棧,提供 fileUpload的攔截器,用於實現文件上傳
步驟一:建立工程環境
建立工廠、導包、配置前端控制器
步驟二:編寫upload.jsp 上傳文件表單
建立頁面
注意:編碼類型必定要寫好
Upload.jsp
<form action="${pageContext.request.contextPath }/uploadAction" enctype="multipart/form-data" method="post">
文件上傳: <input type="file" name="upload">
<input type="submit" value="上傳"/>
</form>
提示:也可使用struts標籤
<s:form action="uploadAction" namespace="/" enctype="multipart/form-data" method="post" theme="simple">
文件上傳:<s:file name="upload"></s:file>
<s:submit value="上傳"/>
</s:form>
Success.jsp:
<body>
<h1>文件上傳成功!</h1>
</body>
步驟二:編寫action
建立action
內容以下:
public class UploadAction extends ActionSupport{
private File upload;//上傳的文件資源,必須和form表單中的上傳標籤中的name屬性一致
private String uploadContentType;//文件類型
private String uploadFileName;//文件名稱
public void setUpload(File upload) {
this.upload = upload;
}
public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
}
public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
}
@Override
public String execute() throws Exception {
FileUtils.copyFile(upload, new File("f:/upload/uploadFileName"));
return super.execute();
}
}
步驟三:Struts.xml:
<struts>
<!-- 配置常量 -->
<constant name="struts.devMode" value="true"></constant>
<!-- 開啓國際化資源文件 -->
<constant name="struts.custom.i18n.resources" value="message"></constant>
<package name="default" extends="struts-default" namespace="/">
<action name="uploadAction" class="cn.itcast.struts.upload.UploadAction">
<result>/upload/success.jsp</result>
</action>
</package>
</struts>
步驟四:測試
上傳文件成功
問題:上傳文件是否是什麼都能上傳,無論文件類型和文件大小都能上傳?
顯然能夠設置文件上傳的限制
在struts2 文件上傳,存在一些限制參數,當違背參數,跳轉 input 視圖
找到上傳的攔截器:經過攔截器中的setter方法獲取參數
經過在action中配置攔截器棧中的fileUpload攔截器的參數, 注意:該配置隻影響當前的action的文件上傳。
【示例】
步驟一:修改struts.xml:設置上傳文件的大小爲1m,只在當前action中生效
注意:顯示上傳單個文件大小校驗錯誤的信息使用<s:fielderror/>,由於struts默認超過單個上傳文件大小限制的錯誤屬於字段錯誤。
<package name="default" extends="struts-default" namespace="/">
<action name="uploadAction" class="cn.itcast.struts.upload.UploadAction">
<interceptor-ref name="defaultStack">
<param name="fileUpload.maximumSize">1097152</param>
</interceptor-ref>
<result>/upload/success.jsp</result>
<result name="input">/upload/upload.jsp</result>
</action>
</package>
步驟二:Jsp頁面:顯示錯誤信息
<body>
<!-- 顯示邏輯錯誤的信息 -->
<s:fielderror/>
<form action="${pageContext.request.contextPath }/uploadAction" enctype="multipart/form-data" method="post">
文件上傳: <input type="file" name="upload">
<input type="submit" value="上傳"/>
</form>
<hr>
<s:form action="uploadAction" namespace="/" enctype="multipart/form-data" method="post" theme="simple">
文件上傳:<s:file name="upload"></s:file>
<s:submit value="上傳"/>
</s:form>
</body>
步驟三:測試
上傳一個超過2m的文件
點擊上傳後結果:報錯,證實限制起做用了。
步驟四:修改錯誤信息提示
英文的錯誤若是看不懂能夠經過覆蓋配置文件常量來自行修改爲中文
更改默認的英文提示:
內置國際化:
找到默認的錯誤信息:
建立一個國際化文件,將默認的錯誤信息覆蓋:
步驟五:再次測試上傳錯誤類型的文件:錯誤信息已修改
步驟六:設置文件上傳的總大小
<!-- 設置文件上傳的總大小爲20m-->
<constant name="struts.multipart.maxSize" value="209715200" />
步驟七:測試上傳超過總大小的文件,好比上傳30M的文件
在頁面顯示錯誤信息必須使用<s:actionerror/>,由於struts2默認爲這是一個邏輯錯誤,因此要使用<s:actionerror/>標籤
使用<s:actionerror/>標籤後錯誤信息顯示以下:
步驟八:將英文的錯誤信息修改爲中文的
仍是找到默認信息的配置文件:
經過錯誤信息的前面幾個英文進行查找,能夠找到錯誤信息的key
在message.properties中自定義錯誤信息:
再次測試上傳一個超過總大小限制的文件,好比30m的文件,錯誤信息顯示以下
步驟一:在xml中配置文件類型的限制:
注意:顯示文件擴展名校驗錯誤的信息使用<s:fielderror>
<package name="default" extends="struts-default" namespace="/">
<action name="upload" class="cn.itcast.struts.upload.UploadAction">
<interceptor-ref name="defaultStack">
<param name="fileUpload.allowedExtensions">.jpg</param>
<param name="fileUpload.maximumSize">2097152</param>
</interceptor-ref>
<result>/upload/success.jsp</result>
<result name="input">/upload/upload.jsp</result>
</action>
</package>
步驟二:修改頁面提示信息:
步驟三:測試
上傳一個.docx的文件
點擊上傳後結果:顯示文件後綴名錯誤
步驟四:修改錯誤信息提示
若是須要改爲中文的錯誤提示:能夠再次到內置國際化信息文件中找到對應的key並在自定義的messages.properties配置文件中配置
配置以下:
步驟五:再次測試
錯誤提示已改爲中文
要點:一個流, 兩個頭信息
Struts2 文件的下載,能夠經過結果集類型stream來實現。
所以注意:文件下載的action必須返回一個結果集視圖,而且該結果集視圖的類型必須是stream
download在struts中是個關鍵字,所以在使用struts.xml配置名稱的時候最好不要用,好比:
不然會報錯以下:
Stream結果集類型:
內容以下:
步驟一:action
注意:必定要返回結果集視圖
public class DownloadAction extends ActionSupport{
@Override
public String execute() throws Exception {
InputStream inputStream = new FileInputStream(new File("f:/a.txt"));
ActionContext.getContext().put("inputStream", inputStream);
System.out.println("nihao");
return SUCCESS;
}
}
步驟二:struts.xml
<!-- 文件下載 -->
<action name="downloadAction" class="cn.itcast.struts.download.DownloadAction">
<result type="stream"></result>
</action>
步驟三:測試
如上這種寫法,其文件的MIME類型以及下載方式已經被固定了,在stream中有默認的方式:
這顯然不符合咱們實際開發的需求,實際開發中,須要按照下載文件的類型來改變MIME類型,並且通常都是經過附件形式進行下載,見下方複雜示例
步驟一:Jsp頁面
建立頁面
內容以下:
<body>
<a href="${pageContext.request.contextPath }/downloadAction?filename=holiday.jpg">下載圖片</a>
<a href="${pageContext.request.contextPath }/downloadAction?filename=塵.mp3">下載mp3</a>
<a href="${pageContext.request.contextPath }/downloadAction?filename=a.txt">下載txt</a>
</body>
步驟二:Action
public class DownloadAction extends ActionSupport{
private String filename;
public void setFilename(String filename) throws Exception {
filename=new String(filename.getBytes("iso8859-1"),"utf-8");
this.filename = filename;
}
@Override
public String execute() throws Exception {
InputStream inputStream = new FileInputStream(new File("f:/"+filename));
//經過文件名稱獲取mime類型
String contentType = ServletActionContext.getServletContext().getMimeType(filename);
//獲取瀏覽器的類型
String agent = ServletActionContext.getRequest().getHeader("User-Agent");
//附件名稱的編碼
String encodeDownloadFilename = encodingFileNameUtil.encodeDownloadFilename(filename, agent);
//將文件類型存入值棧
ActionContext.getContext().put("contentType", contentType);
//將輸入流存入值棧
ActionContext.getContext().put("inputStream", inputStream);
//以附件形式進行下載
String contentDisposition="attachment;filename="+encodeDownloadFilename;
//將下載類型存入到值棧
ActionContext.getContext().put("contentDisposition", contentDisposition);
return SUCCESS;
}
}
步驟三:Struts.xml:
<!-- 配置文件下載 -->
<action name="downloadAction" class="cn.itcast.struts.download.DownloadAction">
<result type="stream">
<param name="contentType">${#contentType}</param>
<param name="contentDisposition">${#contentDisposition}</param>
</result>
</action>
步驟四:測試
執行結果
步驟五:分析
一個流和兩個頭,最終其實仍是從值棧中經過固定的key查詢出來的,所以咱們能夠直接將數據經過對應的key存入值棧就能夠了,而不須要去到struts.xml中配置參數。
Stream代碼:
開發軟件:
考慮系統的架構:你要用什麼技術、要怎麼分層、要用什麼組件 。。。
咱們的架構:struts2+mysql+jquery+dbutil
步驟一:建立工程並導入頁面
導入靜態頁面
效果以下:
步驟二:導入lib,共計16個
建立工具包,導入工具類和配置文件:
struts的lib+dbutil+數據驅動+c3p0
更改數據源配置:將數據源修改爲本身的數據庫配置
步驟三:配置文件
兩個配置文件(web.xml前端控制器-過濾器,核心配置文件struts2.xml)
前端控制器:
Struts.xml
測試環境
請求地址:
顯示以下:
經過分析頁面效果, 要開發功能 :
一、 員工登錄
二、 員工添加 (上傳簡歷 )
三、 員工列表查詢 (多條件 組合查詢 )
四、 員工編輯(回顯,更新)
五、 員工詳細信息查看 (簡歷下載 )
六、 員工刪除 (阻止默認事件發生)
七、自定義攔截器
詳細功能:
* 要完成的功能: * 把普通的html標籤替換爲struts2標籤 * 登陸 * 用戶名和密碼用struts2驗證框架進行驗證
* 首頁完善 * 顯示當前的用戶名
* 用戶的添加 包含文件上傳,配置參數(臨時路徑總開關 3三個配置 struts2驗證框架表單重複提交)
* 用戶的條件查詢
* 用戶的編輯(文件上傳)
* 用戶的修改 包含文件上傳,表單重複提交
* 用戶的刪除
* 查看 包含文件下載)
* 自定義攔截器(驗證用戶登陸)
|
準備工具:mysql
通常企業開發的時候,不會用root用戶。root主要用來管理用。
通常咱們都創建新的用戶和數據,而後對應一個項目。
1.創建數據庫usermanage---root先登陸
編碼是跟你數據庫配置有關係。默認值在my.ini的文件中配置的,若是沒有配置默認編碼,那麼建議你手動選擇,不然會出現編碼問題。
[mysqld] #服務端編碼配置 character-set-server=utf8 |
手動選擇:
2.創建用戶,而且受權
主機:%表明其餘任何的機器能夠訪問,localhost:本機能夠訪問
將剛纔創建的表受權給新建的用戶:
命令腳本:
grant all on struts2_em17.* to struts2_em17;
從新用新建的用戶登陸:
#用戶表 CREATE TABLE S_User( userID INT NOT NULL AUTO_INCREMENT, #主鍵ID userName VARCHAR(50) NULL, #用戶姓名 logonName VARCHAR(50) NULL, #登陸名 logonPwd VARCHAR(50) NULL, #密碼# sex VARCHAR(10) NULL, #性別(例如:男,女) birthday VARCHAR(50) NULL, #出生日期 education VARCHAR(20) NULL, #學歷(例如:研究生、本科、專科、高中) telephone VARCHAR(50) NULL, #電話 interest VARCHAR(20) NULL, #興趣愛好(例如:體育、旅遊、逛街) path VARCHAR(500) NULL, #上傳路徑(path路徑) filename VARCHAR(100) NULL, #上傳文件名稱(文件名) remark VARCHAR(500) NULL, #備註 PRIMARY KEY (userID) ) ;
#初始化數據:默認用戶名和密碼是admin INSERT INTO s_user (userID,userName,logonName,logonPwd) VALUES (1,'超級管理員','admin','admin'); |
運行腳本:先選中數據庫,而後將腳本粘貼進窗口,而後運行:
刷新用F5
業務流程:當用戶輸入用戶名密碼後,若是經過,則跳到首頁,若是不經過,則跳回來。
分析:表單校驗。好比:不能不輸入。要求:用戶名和密碼必須都輸入。
後臺邏輯:當登陸成功了,將用戶放入session。
目標:要將普通的表單,改形成struts2的表單。
爲何?struts表單,用起來比較方便,簡單,並且你用struts開發,用s標籤,能夠表單回顯。
運行發現樣式發生變化:
緣由是struts2有內置樣式,解決方案:將內置的樣式去掉。
struts.xml:
public String login(){
UserService userService = new UserService();
User queryUser=userService.findUser(user);
if (queryUser==null) {
//添加錯誤提示信息
this.addActionError("用戶名或者密碼錯誤!");
return LOGIN;
}else{
//登陸成功將信息存入到session中
ServletActionContext.getRequest().getSession().setAttribute("user", queryUser);
return SUCCESS;
}
public class UserService {
public User findUser(User user) {
UserDao userDao = new UserDao();
return userDao.findUser(user);
}
}
public class UserDao {
public User findUser(User user) {
QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());
String sql = "select * from s_user where logonName=? and logonPwd=?";
try {
return queryRunner.query(sql, new BeanHandler<User>(User.class),
user.getLogonName(), user.getLogonPwd());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException("根據用戶名和密碼查詢用戶失敗!");
}
}
}
<package name="default" namespace="/" extends="struts-default">
<!-- 用戶管理 -->
<action name="user_*" class="cn.itcast.usermanage.web.UserAction" method="{1}">
<result type="redirect">/login/home.jsp</result>
<!-- 登陸校驗錯誤跳轉視圖 -->
<result name="login">/login/login.jsp</result>
</action>
</package>
登陸錯誤提示:
配置Xml校驗文件:
配置校驗文件:通常用局部校驗。(一個功能表單對應一個校驗,每一個表單的提示錯誤信息可能都不同。):格式:在action類的包中創建一個文件:action類名-action的名字-validation.xml
步驟一:建立校驗文件
校驗內容:
<validators>
<field name="logonName">
<field-validator type="requiredstring">
<message key="LogonName.required"></message>
</field-validator>
</field>
<field name="logonPwd">
<field-validator type="requiredstring">
<message key="LogonPwd.required"></message>
</field-validator>
</field>
</validators>
步驟二:配置國際化信息
內容:
步驟三:Action
登陸錯誤的信息提示從國際化信息文件中獲取
public String login(){
UserService userService = new UserService();
User queryUser=userService.login(user);
if (queryUser==null) {
//添加錯誤提示信息
this.addActionError(this.getText("LoginError"));
return LOGIN;
}else{
//登陸成功將信息存入到session中
ServletActionContext.getRequest().getSession().setAttribute("user", queryUser);
return SUCCESS;
}
}
步驟四:Struts.xml
開啓國際化信息機制
具體配置內容:配置校驗失敗跳轉的結果集視圖
<struts>
<!-- 配置一個開發者模式 -->
<constant name="struts.devMode" value="true"></constant>
<!-- 修改strute標籤樣式爲簡單樣式 -->
<constant name="struts.ui.theme" value="simple"></constant>
<!-- 開啓國際化信息機制 -->
<constant name="struts.custom.i18n.resources" value="message"></constant>
<!-- package:包 name:包名,必須保證惟一性 extends:繼承struts-default namespace:名稱空間 -->
<package name="default" extends="struts-default" namespace="/">
<!-- 設置action -->
<action name="user_*" class="cn.itcast.struts.action.UserAction" method="{1}">
<!-- 登陸失敗跳轉的結果集視圖 -->
<result name="login">/login/login.jsp</result>
<!-- 若是登陸成功,跳轉到home.jsp -->
<result type="redirect">/login/home.jsp</result>
<!-- 配置字段校驗失敗跳轉的input結果集視圖 -->
<result name="input">/login/login.jsp</result>
</action>
</package>
</struts>
步驟五:jsp頁面
添加校驗錯誤提示
步驟六:測試
什麼都不寫提交表單
【擴展】
表單錯誤信息的局部顯示
樣式想跟在後面,須要手動更改模版。
擴展補充:
關於struts2的這個三個:區別
優化一:
頁面顯示用戶名:並無顯示數據庫中的用戶名,顯然是寫死了。
找到所在的jsp頁面:
將原來寫死的數據改爲用EL表達式來從session中獲取。
優化二:
登陸成功後顯示頁面:
top.jsp頁面:
首頁重定向:
<!-- 用戶登陸 -->
<action name="user_*" class="cn.itcast.struts.actoin.UserAction" method="{1}">
<!-- 配置登陸成功後須要響應的結果集視圖 -->
<result type="redirect">/login/home.jsp</result>
<!-- 登陸失敗後須要跳轉的結果集視圖 -->
<result name="login">/login/login.jsp</result>
<result name="input">/login/login.jsp</result>
</action>
需求功能分析:將表單數據保存到數據庫
JQuery有不少插件,幫助咱們作一些效果或者功能。
jQuery官方+第三方都提供了一些插件(easyUI)。
官方的插件:jQuery ui
下載:
解壓查看全部插件效果(查看index.html便可):
集成方式:
步驟一:導入js庫和樣式:
步驟二:頁面引入:
參考使用:
Datepicker
步驟三:jqueryui.jsp
彈出的插件:
將普通的form表單改爲struts表單
分析:
給登陸名、密碼、用戶姓名添加一個非空的針對方法的局部表單校驗
步驟一:action
新增一個add方法,須要作局部的表單校驗
public String add() throws IOException{
System.out.println("新增用戶成功!");
return SUCCESS;
}
步驟二:添加xml局部校驗文件
步驟三:編寫的國際化信息
步驟四:頁面上顯示錯誤信息:
步驟五:測試
校驗錯誤跳轉input視圖,而此時咱們應該讓其從新跳轉到add.jsp,從新新增用戶。
錯誤緣由:struts.xml中咱們已經配置過一個登陸失敗時跳轉的input視圖,如今新增用戶校驗失敗的話也會跳轉到以前配置input視圖,但是這個input視圖配置的結果集並非咱們想要的,咱們在新增用戶校驗失敗的時候須要從新跳轉到新增用戶—add.jsp頁面。而一個action中只能配置一個input視圖,此時該怎麼辦?
分析:看workflow攔截器是否是有推薦的解決方案。
核心文件中:攔截器:負責錯誤頁面的跳轉:
進入到這個類中發現註釋中有使用標籤來修改結果集的簡介
步驟六:添加input視圖跳轉的註解
//添加用戶
//能夠手動更改校驗錯誤發生是跳轉的結果集視圖
@InputConfig(resultName="addError")
public String add(){
System.out.println("用戶新增成功");
return "add";
}
Struts.xml:添加addinput視圖的跳轉
<!-- 設置action -->
<action name="user_*" class="cn.itcast.struts.action.UserAction" method="{1}">
<!-- 登陸失敗跳轉的結果集視圖 -->
<result name="login">/login/login.jsp</result>
<!-- 若是登陸成功,跳轉到home.jsp -->
<result type="redirect">/login/home.jsp</result>
<!-- 配置字段校驗失敗跳轉的input結果集視圖 -->
<result name="input">/login/login.jsp</result>
<!-- 配置校驗失敗的結果集視圖 -->
<result name="addError">/user/add.jsp</result>
</action>
步驟七:再次測試
結果:校驗錯誤後仍是返回add.jsp頁面,無誤。
保存的時候要注意兩個操做:
步驟一:Action
//添加用戶
//能夠手動更改校驗錯誤發生是跳轉的結果集視圖
@InputConfig(resultName="addError")
public String add(){
UserService userService = new UserService();
userService.add(user);
return "add";
}
步驟二:Service
public void add(User user) {
new UserDao().add(user);
}
步驟三:Dao
public void add(User user) {
QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());
String sql = "insert into s_user values(null,?,?,?,?,?,?,?,?,?,?,?)";
try {
queryRunner.update(sql, user.getUserName(), user.getLogonName(),
user.getLogonPwd(), user.getSex(), user.getBirthday(),
user.getEducation(), user.getTelephone(),
user.getInterest(), user.getPath(), user.getFilename(),
user.getRemark());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException("新增用戶失敗!");
}
}
步驟四:Struts.xml:
<package name="default" extends="struts-default" namespace="/">
<!-- 設置action -->
<action name="user_*" class="cn.itcast.struts.action.UserAction" method="{1}">
<!-- 登陸失敗跳轉的結果集視圖 -->
<result name="login">/login/login.jsp</result>
<!-- 若是登陸成功,跳轉到home.jsp -->
<result type="redirect">/login/home.jsp</result>
<!-- 配置字段校驗失敗跳轉的input結果集視圖 -->
<result name="input">/login/login.jsp</result>
<!-- 配置校驗失敗的結果集視圖 -->
<result name="addError">/user/add.jsp</result>
<!-- 配置新增用戶成功後跳轉的結果集視圖 -->
<result name="add">/user/list.jsp</result>
</action>
</package>
步驟五:測試
測試保存:發現有兩個字段沒有數據,一個是路徑,一個是文件名,這兩個是和上傳簡歷有關的字段。
思考:在簡歷上傳完成以後是否是要保存到一個指定的路徑,那麼這個路徑保存的時候要考慮會不會重複,所以須要給保存的文件設置一個隨機的不會重複的路徑。
在第四天的課前資料裏面有一個工具類,能夠自動生成一個隨機的文件名和二級目錄,能夠將該工具類複製到utils包下:
內容以下:
有了隨機的目錄和文件名,只要再指定一個盤符保存就好了,爲了使用方便,這個盤符咱們能夠設置成一個常量,而這個常量咱們也能夠建立一個類來調用它,以下:這個常量好處是節省資源,只會初始化一次。
內容以下:其實只是一個保存路徑的前半段而已。
上傳文件須要注意的要點:
一、form表單提交方式必須是post,enctype屬性必須是= multipart/form-data
二、必須有一個上傳文件的標籤
開始編寫上傳邏輯
保存分兩步進行:
第一步:先保存文件到服務器
依賴於攔截器:
步驟一:action
添加上傳文件須要的屬性
以上這三個屬性原來咱們是直接寫在action中的,可是顯示若是分了三層以後上傳的邏輯更加適合寫在service層中,而爲了傳遞參數方便,所以咱們能夠將這個三個屬性寫到user對象中去而且提供getter和setter方法,這樣傳遞到service層進行業務邏輯處理的時候顯然方便不少。。
修改user:
在add方法中添加上傳邏輯:
//新增用戶
@InputConfig(resultName="addError")
public String add(){
UserService userService = new UserService();
userService.add(user);
return "add";
}
步驟二:service添加上傳邏輯
public void add(User user) {
try {
//添加一個用戶是否上傳文件的判斷,避免空指針錯誤
if (user.getUpload()!=null) {
String uploadFileName = user.getUploadFileName();
//生成一個uuid文件名
String uuid = UploadUtils.generateRandonFileName(uploadFileName);
//生成一個二級目錄
String dir = UploadUtils.generateRandomDir(uuid);
//生成一個指定保存簡歷的路徑
String realPath=SystemConstant.Default_DIR+dir+"/"+uuid;
user.setPath(realPath);
user.setFilename(uploadFileName);
File upload = user.getUpload();
//保存簡歷到指定的路徑
FileUtils.copyFile(upload, new File(realPath));
}
new UserDao().add(user);
} catch (IOException e) {
e.printStackTrace();
}
}
步驟三:測試
上傳成功
步驟四:設置上傳簡歷的大小和後綴名
文件上傳大小的設置:
struts.xml文件中的大小與實際文件大小的關係:1048576(Bytes) = 1024*1024 = 1M實際文件大小。
struts有兩個地方來限制文件上傳大小的!
1)核心配置文件中的常量
2)在struts.xml中的action標籤裏配置:
局部的文件上傳參數:
<action name="user_*" class="cn.itcast.usermanage.web.UserAction"
method="{1}">
<!-- 設置局部上傳文件大小和擴展名 -->
<interceptor-ref name="defaultStack">
<param name="fileUpload.maximumSize">2097152</param>
<param name="fileUpload.allowedExtensions">.doc,.avi,.docx,.txt,.mp3</param>
</interceptor-ref>
<!-- 登陸失敗跳轉的結果集視圖 -->
<result name="login">/login/login.jsp</result>
<result type="redirect">/login/home.jsp</result>
<!-- 登陸校驗錯誤跳轉視圖 -->
<result name="input">/login/login.jsp</result>
<result name="add">/user/list.jsp</result>
<!-- 新增用戶校驗錯誤跳轉視圖 -->
<result name="addError">/user/add.jsp</result>
</action>
或者在package下設置全局的文件上傳參數:
<package name="default" namespace="/" extends="struts-default">
<!-- 設置全局上傳文件的大小和擴展名 -->
<interceptors>
<interceptor-stack name="mydefault">
<interceptor-ref name="defaultStack">
<!-- 限制上傳文件大小 -->
<param name="fileUpload.maximumSize">2097152</param>
<!-- 限制上傳文件擴展名 -->
<param name="fileUpload.allowedExtensions">.doc,.avi,.docx,.txt,.mp3</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 覆蓋默認攔截器棧 -->
<default-interceptor-ref name="mydefault"></default-interceptor-ref>
<!-- 用戶管理 -->
<action name="user_*" class="cn.itcast.usermanage.web.UserAction"
method="{1}">
<!-- 登陸失敗跳轉的結果集視圖 -->
<result name="login">/login/login.jsp</result>
<result type="redirect">/login/home.jsp</result>
<!-- 登陸校驗錯誤跳轉視圖 -->
<result name="input">/login/login.jsp</result>
<result name="add">/user/list.jsp</result>
<!-- 新增用戶校驗錯誤跳轉視圖 -->
<result name="addError">/user/add.jsp</result>
</action>
</package>
上面局部和全局的兩選其一便可
步驟三:測試
上傳一個4M的文件:報錯出現內置錯誤提示
問題:文件大小在全局設置和局部設置,這兩種有什麼區別:
the request was rejected because its size (16272982) exceeds the configured maximum (9000000)
或者以下:
又或者服務器系統就直接拋出沒有響應的錯誤。
或者
當上傳的文件在struts.multipart.maxSize和maximumSize之間時,系統提示:
File too large: file "MSF的概念.ppt" "upload__5133e516_129ce85285f__7ffa_00000005.tmp" 6007104
結論:全局通常設置大一些,局部的通常根據要求設置。
【錯誤信息的國際化覆蓋】
找到錯誤信息提示:
覆蓋:將該錯誤提示信息寫如message.properties國際化文件中
用中文覆蓋原提示便可
再次測試:
需求:若是用戶名在數據庫中已經存在,那麼我將提醒用戶,而且不容許提交。
技術:ajax
開發分析:失去焦點後,登陸名後面提示,提交按鈕禁用掉。
修改頁面,增長ajax的前端代碼:使用異步請求接收響應的json數據。
問題:爲何不能直接將數據存入值棧,而後頁面獲取值棧信息進行判斷用戶是否存在呢?
緣由:異步請求,當回調函數獲取data數據的時候,響應已經結束了,而值棧的生命週期是從一個請求開始到響應結束,所以值棧的生命週期已通過了,值棧內沒有數據了。
struts內置了json的轉換器(可以自動將java對象轉換成json,而且能夠自動放入響應reponse中)。struts2-json-plugin插件中。
能自動將值棧中的某個對象,自動轉換成json,而且自動放入響應。
咱們就只須要將要異步請求的結果,放入值棧就能夠了。插件會自動去拿。
注意:須要修改<package name="default" namespace="/" extends="json-default">
首先在登陸名標籤下面添加一個span標籤用來添加提示信息
其次能夠經過該標籤的html來添加提示信息。
$(document).ready(function(){
//使用class屬性處理 'yy-mm-dd' 設置格式"yyyy/mm/dd"
$('#birthday').datepick({dateFormat: 'yy-mm-dd'});
$("#userAction_save_do_logonName").blur(function(){
$.post("${pageContext.request.contextPath}/user_checkUserExist",{"logonName":$(this).val()},function(data){
if(!data.isExist){
$("#checkUser").html("<font color='green'>能夠註冊!</font>");
$("#userAction_save_do_submit").removeAttr("disabled");
}else{
$("#checkUser").html("<font color='red'>登陸名已存在!</font>");
$("#userAction_save_do_submit").attr({"disabled":"disabled"});
}
});
});
});
/**
* 異步請求校驗登陸名是否存在
* @return
*/
//異步請求校驗,檢查登陸名是否存在
public String checkUserExist(){
UserService userService = new UserService();
User queryUser=userService.checkUserExist(user);
Map map = new HashMap();
if (queryUser==null) {
map.put("isExist", false);
}else{
map.put("isExist", true);
}
//第一種轉換成json數據的方法:壓入棧頂
/*ActionContext.getContext().getValueStack().push(map);*/
//第二種轉換成json數據的方法:將數據存入到值棧
ActionContext.getContext().put("json", map);
return "checkUserExist";
}
修改package的繼承包:
配置結果集:
<!-- 用戶登陸 -->
<action name="user_*" class="cn.itcast.struts.action.UserAction" method="{1}">
<!-- 登陸失敗跳轉的結果集視圖 -->
<result name="login">/login/login.jsp</result>
<!-- 若是登陸成功,跳轉到home.jsp -->
<result type="redirect">/login/home.jsp</result>
<!-- 配置字段校驗失敗跳轉的input結果集視圖 -->
<result name="input">/login/login.jsp</result>
<!-- 配置校驗失敗的結果集視圖 -->
<result name="addError">/user/add.jsp</result>
<!-- 配置新增用戶成功後跳轉的結果集視圖 -->
<result name="add">/user/list.jsp</result>
<!-- 轉換成json數據必須使用json的結果集類型:第一種寫法 -->
<!-- <result name="checkUserExist" type="json"></result> -->
<!-- 轉換成json數據必須使用json的結果集類型:第二種寫法 -->
<result name="checkUserExist" type="json">
<param name="root">json</param>
</result>
</action>
測試無誤
打開json插件包下的struts-plugin.xml
原理:
怎麼進行響應數據?
響應的數據怎麼來的?
由此原理分析可見,響應json數據有兩種寫法
步驟三:測試
測試效果和第一種方法一致。
問題:爲何不在struts.xml中使用$以下取數據?
區別:
${ognl表達式},你在xml等配置文件中,直接要獲取值棧中的某個值的時候,用這個。
而在源碼中須要的root是一個參數,這個參數是一個字符串:
無條件查詢
分析功能:
將數據從數據庫查詢出來,放入值棧,頁面使用struts的循環標籤(<s:iterator>)進行打印便可。
/login/left.jsp
/**
* 查找全部用戶
* @return
*/
//查詢全部用戶
public String list(){
UserService userService = new UserService();
List<User> userList=userService.queryList();
//將查到的全部用戶存入到值棧
ActionContext.getContext().put("userList", userList);
return "list";
}
Service:
// 查詢全部用戶
public List<User> queryList() {
UserDao userDao = new UserDao();
List<User> userList = userDao.queryList();
return userList;
}
dao:
//查詢全部用戶
public List<User> queryList() {
QueryRunner runner = new QueryRunner(JDBCUtils.getDataSource());
String sql = "select * from s_user";
try {
return runner.query(sql, new BeanListHandler<User>(User.class));
} catch (SQLException e) {
throw new RuntimeException("異步校驗檢查用戶是否存在失敗!");
}
}
導入strut是標籤
將原來寫死的數據刪除後替換以下:
<s:iterator value="userList" var="user">
<tr onmouseover="this.style.backgroundColor = 'white'"
onmouseout="this.style.backgroundColor = '#F5FAFE';">
<td style="CURSOR: hand; HEIGHT: 22px" align="center"
width="18%">
<s:property value="logonName"/>|<s:property value="#user.logonName"/>|${logonName }
</td>
<td style="CURSOR: hand; HEIGHT: 22px" align="center"
width="17%">
<s:property value="userName"/>|<s:property value="#user.userName"/>|${userName }
</td>
<td style="CURSOR: hand; HEIGHT: 22px" align="center"
width="8%">
<s:property value="sex"/>|<s:property value="#user.sex"/>|${user.sex }
</td>
<td style="CURSOR: hand; HEIGHT: 22px" align="center"
width="23%">
<s:property value="telephone"/>|<s:property value="#user.telephone"/>|${telephone }
</td>
<td style="CURSOR: hand; HEIGHT: 22px" align="center">
<s:property value="education"/>|<s:property value="#user.education"/>|${education }
</td>
<td align="center" style="HEIGHT: 22px">
<a href="${pageContext.request.contextPath}/user/edit.jsp?userID=15">
<img src="${pageContext.request.contextPath}/images/i_edit.gif" border="0" style="CURSOR: hand">
</a>
</td>
<td align="center" style="HEIGHT: 22px">
<a href="${pageContext.request.contextPath}/user/view.jsp?userID=15">
<img src="${pageContext.request.contextPath}/images/button_view.gif" border="0" style="CURSOR: hand">
</a>
</td>
<td align="center" style="HEIGHT: 22px">
<a href="${pageContext.request.contextPath}/user/list.jsp?userID=15">
<img src="${pageContext.request.contextPath}/images/i_del.gif" width="16" height="16" border="0" style="CURSOR: hand">
</a>
</td>
</tr>
</s:iterator>
當新增用戶成功以後,跳轉回查詢列表頁面:
<!-- 設置action -->
<action name="user_*" class="cn.itcast.struts.action.UserAction" method="{1}">
<!-- 登陸失敗跳轉的結果集視圖 -->
<result name="login">/login/login.jsp</result>
<!-- 若是登陸成功,跳轉到home.jsp -->
<result type="redirect">/login/home.jsp</result>
<!-- 配置字段校驗失敗跳轉的input結果集視圖 -->
<result name="input">/login/login.jsp</result>
<!-- 配置校驗失敗的結果集視圖 -->
<result name="addError">/user/add.jsp</result>
<!-- 配置新增用戶成功後跳轉的結果集視圖 -->
<result name="add">/user/list.jsp</result>
<!-- 轉換成json數據必須使用json的結果集類型:第一種寫法 -->
<!-- <result name="checkUserExist" type="json"></result> -->
<!-- 轉換成json數據必須使用json的結果集類型:第二種寫法 -->
<result name="checkUserExist" type="json">
<param name="root">json</param>
</result>
<!-- 查詢全部用戶成功後條件結果集視圖 -->
<result name="list">/user/list.jsp</result>
</action>
新增用戶後跳轉到list.jsp,而且顯示全部用戶信息,測試無誤。
邏輯執行的流程圖:
小結
做業:
一、今天的練習。
二、上傳簡歷的添加文件大小和文件類型的限制。
三、作完以後:將條件查詢作完。。*(就是一個sql拼接,改表單-數據模型有對應的屬性)