result 結(jié)果集
<result>元素的type屬性用來指定結(jié)果類型!如果沒有指定type時,默認(rèn)為dispatcher,下面介紹5種常用的結(jié)果類型。
1,dispathcer:默認(rèn)值: 表示轉(zhuǎn)發(fā)到頁面
<result name="success" type="dispatcher">
<param name="location">foo.jsp</param>
</result>
2,stream:表示轉(zhuǎn)發(fā)到另一個Action,所以這時<result>元素的內(nèi)容需要是另一個<action>的名字;
<result name="download" type="stream">
<param name="contentType">image/png</param>
<param name="inputName">avatar</param>
<param name="contentDisposition">attachment;filename="${uploadName}"</param>
<param name="bufferSize">10240</param>
</result>
3,redirect:表示重定向到頁面
The redirect URL generated will be:
foo.jsp#FRAGMENT
<result name="success" type="redirect">
<param name="location">foo.jsp</param>
<param name="parse">false</param>
<param name="anchor">FRAGMENT</param>
</result>
<result name="home" type="redirect">/login/home.jsp</result>
4,redirectAction:表示重定向到另一個Action。
<result name="rlist" type="redirectAction">
<param name="actionName">userAction_list</param>
<param name="namespace">/p</param>
</result>
5,textplain:表示將以文本的形式發(fā)送資源。
<action name="displayJspRawContent" >
<result type="plainText">/myJspFile.jsp</result>
</action>
<action name="displayJspRawContent" >
<result type="plainText">
<param name="location">/myJspFile.jsp</param>
<param name="charSet">UTF-8</param>
</result>
</action>
封裝請求參數(shù)
屬性封裝
只要在Action 中提供與參數(shù)對應(yīng)的get/set方法即可自動封裝。
public class ParamseAction extends ActionSupport {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String execute() throws Exception {
System.out.println("username = "+username);
return SUCCESS;
}
}
類型轉(zhuǎn)換
默認(rèn)支持類型轉(zhuǎn)換。
- 字符串 -> 指定類型 之間轉(zhuǎn)換
字符串 轉(zhuǎn)成 指定類型:表單提交,瀏覽器發(fā)送服務(wù)器
指定類型 轉(zhuǎn)成 字符串;標(biāo)簽回顯,服務(wù)器發(fā)送瀏覽器
自定義類型轉(zhuǎn)換器
實(shí)現(xiàn)類
方案1:實(shí)現(xiàn)接口:TypeConverter,有一個方法,但參數(shù)過多。
方法2:繼承默認(rèn)實(shí)現(xiàn)類:DefaultTypeConverter 。提供簡潔方法convertValue(Object , Class)
convertValue(Object value , Class toType)
#1 表單提交,瀏覽器發(fā)送到服務(wù)器。瀏覽器發(fā)送的肯定字符串String,需要轉(zhuǎn)換成指定的類型。例如Date類型
參數(shù)1:value,表示瀏覽器發(fā)送的數(shù)據(jù)。類型是String[] ,底層使用request.getParameterValues("...")
參數(shù)2:toType,表示需要轉(zhuǎn)換的類型,java.uilt.Date類型
** 操作
// 如果toType是 Date類型,表示希望將 字符串轉(zhuǎn)成 時間
if(toType == java.util.Date.class){
//獲得數(shù)據(jù)
String[] params = (String[])value;
//轉(zhuǎn)成成時間
}
#2 標(biāo)簽回顯,服務(wù)器發(fā)送 瀏覽器,類型之前已經(jīng)從字符串轉(zhuǎn)成時間,現(xiàn)在希望將時間再轉(zhuǎn)換成 字符串。
參數(shù)1:value,表示服務(wù)器已經(jīng)轉(zhuǎn)成好的時間。類型Date。
參數(shù)2:toType,表示需要轉(zhuǎn)換的類型,String類型
** 操作
if(toType == String.class){
// 將數(shù)據(jù)強(qiáng)轉(zhuǎn)時間
Date date = (Date)value;
// 格式化
}
public class MyDateConverter extends DefaultTypeConverter {
@Override
public Object convertValue(Object value, Class toType) {
System.out.print("正在轉(zhuǎn)換");
SimpleDateFormat sb = new SimpleDateFormat("yyyy/MM/dd");
try {
//String——>date
if(toType == Date.class) {
String[] params = (String[]) value;
return sb.parse(params[0]);
}
//date->String
if(toType == String.class) {
Date date = (Date) value;
return sb.format(date);
}
} catch (ParseException e) {
e.printStackTrace();
}
throw new RuntimeException("參數(shù)錯誤");
}
}
配置文件
位置:action類同包
名稱:actionClass-conversion.properties
例:StrutsFormAction-conversion.properties
birthday=cn.structs.h_parmase.MyDateConverter
數(shù)據(jù)校驗(yàn)
實(shí)現(xiàn)接口,并編寫方法 validate方法() , 此處“方法”表示執(zhí)行的方法名稱,首字母大寫。
例如:add() 執(zhí)行前需要校驗(yàn),必須編寫 validateAdd()
validateLogin()
提示錯誤
addFieldError("", "") 給指定的字段設(shè)置提示信息
<s:fielderror>jsp顯示錯誤
addActionMessage(aMessage) action提示提示信息
<s:actionmessage/>jsp顯示錯誤
addActionError(anErrorMessage) action錯誤
<s:actionerror/>jsp顯示錯誤
public void validateLogin() {
clearFieldErrors();
if (StringUtils.isEmpty(user.getLoginname())) {
addFieldError("loginname", "用戶名不能為空");
}
if (StringUtils.isEmpty(user.getLoginpass())) {
addFieldError("loginpass", "密碼不能為空");
}
}
攔截器
攔截器介紹
struts提供攔截器,對action類進(jìn)行增強(qiáng)的。struts已經(jīng)實(shí)現(xiàn)多個攔截器,完成不同的功能。
例如:文件上傳、數(shù)據(jù)校驗(yàn)、類型轉(zhuǎn)換、參數(shù)封裝等.
默認(rèn)攔截者棧
truts-default.xml 提供struts完成所有攔截器,也提供默認(rèn)攔截器棧
<default-interceptor-ref name="defaultStack"/> 所有的action默認(rèn)使用那個攔截器棧
<interceptor-stack name="defaultStack"> 聲明一個攔截器棧,名稱為“defaultStack”,通常稱為:默認(rèn)攔截器棧
- servletConfig : 用于給action類注入Servlet api。
例如:action類實(shí)現(xiàn)ServletRequestAware就可以被struts框架注入HttpServletRequest對象 - modelDriven: 調(diào)用action類的getModel()方法,獲得javabean實(shí)例,如果沒為null,將交予struts。
- fileUpload:struts默認(rèn)支持文件上傳。
- params:給action類進(jìn)行數(shù)據(jù)封裝。如果使用ModelDriven,就給javabean封裝數(shù)據(jù)。
- conversionError:將轉(zhuǎn)換錯誤添加到action類的錯誤提示信息中。
將執(zhí)行 action.addFieldError("屬性","錯誤提示"); - validation:將執(zhí)行action所有校驗(yàn)。先執(zhí)行注解校驗(yàn),再執(zhí)行單個方法校驗(yàn),最后所有方法的校驗(yàn)
- workflow :從action類獲得添加的錯誤信息,如果沒有發(fā)行。如果有返回“input”
自定義攔截器
實(shí)現(xiàn)接口:com.opensymphony.xwork2.interceptor.Interceptor。
繼承父類:com.opensymphony.xwork2.interceptor.MethodFilterInterceptor。
在使用自定義攔截器,可以對指定的方法進(jìn)行操作(哪些方法不攔截,哪些必須攔截)
設(shè)置屬性includeMethods,確定哪些方法進(jìn)行攔截
設(shè)置屬性excludeMethods,確定哪些方法不進(jìn)行攔截<default-interceptor-ref name="xxx">將指定的攔截器,聲明成默認(rèn)的。
注意:如果使用自定義xxx,“defaultStack”將被覆蓋。注意:攔截器只攔截action類,不攔截jsp文件。
示例 是否登陸攔截器
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="project" namespace="/p" extends="struts-default">
<interceptors>
<interceptor name="login" class="cn.project.action.LoginInterceptor"></interceptor>
<interceptor-stack name="myDefaultStarck">
<interceptor-ref name="login">
<param name="excludeMethods">login</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myDefaultStarck"></default-interceptor-ref>
<!--配置全局錯誤-->
<global-exception-mappings>
<exception-mapping exception="cn.project.exception.UserException" result="error"></exception-mapping>
</global-exception-mappings>
<action name="userAction_*" class="cn.project.action.UserAction" method="{1}">
<result name="error">/user/error1.jsp</result>
<result name="login">/login/login.jsp</result>
<result name="input">/login/login.jsp</result>
<result name="list">/user/list.jsp</result>
<result name="view">/user/view.jsp</result>
<result name="edit">/user/edit.jsp</result>
<result name="rlist" type="redirectAction">
<param name="actionName">userAction_list</param>
<param name="namespace">/p</param>
</result>
<result name="download" type="stream">
<param name="contentType">image/png</param>
<param name="inputName">avatar</param>
<param name="contentDisposition">attachment;filename="${uploadName}"</param>
<param name="bufferSize">10240</param>
</result>
<result name="home" type="redirect">/login/home.jsp</result>
</action>
</package>
</struts>
public class LoginInterceptor extends MethodFilterInterceptor {
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
Map<String, Object> sessionScope = ActionContext.getContext().getSession();
ProjectUser user = (ProjectUser) sessionScope.get("user");
if(user == null) {
return "login";
}
return invocation.invoke();
}
}