摘自视频学习笔记
基于请求驱动的(struts 1.x ,struts2.x ,Web work)
基于事件驱动的(JSF)
07_Struts MVC框架实现原理.avi
Model2:
Struts MVC框架
Struts框架组件
l ActionServlet类控制导航
l ActionServlet根据URI来决定哪个Ation类被用于处理请求,Ation可以校验输入,并访问业务层以便从数据库检索信息
l Action需要知道页面提交了哪些内容,所以由ActionServlet根据请求URI来决定将请求参数绑定到哪个ActionForm中,并传入Action
l Action在完成业务逻辑后,返回一个ActionForward对象,ActionServlet根据ActionForward对象中的路径来调用页面完成响应
l Struts将这些信息绑定在一个ActinMapping对象中,一个ActionMapping对应一个请求URI,当请求路径到达时,ActionServlet就会查询ActionMapping对象,ActionMapping对象将告诉ActionServlet哪个Action类会被调用、哪个ActionForm类被用于传递页面数据以及那些ActionForward将被用于转向
l 有关Action、ActionForm、ActionForward等信息,Struts通过一个配置文件:struts-config.xml来定义
08_基于Struts的第一个项目_1.avi
1、配置struts
* 拷贝struts lib下的所有jar到WEB-INF/lib下
* 修改web.xml文件,配置ActionServlet
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<!-- Standard Action Servlet Mapping -->
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
* 提供struts-config.xml文件
3、创建登录项目
* 创建jsp页面(login.jsp,login_success.jsp,login_error.jsp)
* 创建LoginActionForm.java
* 创建LoginAction.java
* 配置struts-config.xml文件
<form-beans>
<form-bean name="loginForm" type="com.bjsxt.struts.LoginActionForm"/>
</form-beans>
<action-mappings>
<action path="/login"
type="com.bjsxt.struts.LoginAction"
name="loginForm"
scope="request"
validate="false">
<forward name="success" path="/login_success.jsp"/>
<forward name="error" path="/login_error.jsp"/>
</action>
</action-mappings>
11_基于Struts的第一个项目执行流程分析.avi
struts标签的配置和使用
配置:
* 在struts-config.xml文件中加入
<message-resources parameter="MessageResources" />
* 拷贝MessageResources.properties文件到src下
使用:
* 采用taglib指令引入
<%@ taglib prefix="bean" uri="http://struts.apache.org/tags-bean"%> <%@ taglib prefix="logic" uri="http://struts.apache.org/tags-logic"%>
常用标签:
<bean:write>
<logic:empty> 和 <logic:notEmpty>
<logic:present> 和 <logic:notPresent>
<logic:iterator>
16_Struts BeanWrite标签.avi
一.bean:write
//普通属性
request.setAttribute("hello", "Hello World");
//html文本
request.setAttribute("bj", "<font color='red'>北京欢迎您</font>");
//日期
request.setAttribute("today", new Date());
//数字
request.setAttribute("n", 123456.987);
//结构
Group group = new Group();
group.setName("尚学堂");
User user = new User();
user.setUsername("张三");
user.setAge(18);
user.setGroup(group);
request.setAttribute("user", user);
<li>普通字符串</li><br>
hello(jsp脚本):<%=request.getAttribute("hello") %><br>
hello(标签):<bean:write name="hello"/><br>
<p>
<li>html文本</li><br>
bj(default):<bean:write name="bj"/><br>
bj(filter="true"):<bean:write name="bj" filter="true"/><br>
bj(filter="false"):<bean:write name="bj" filter="false"/><br>
<p>
<li>格式化日期</li><br>
today(default):<bean:write name="today"/><br>
today(format="yyyy-MM-dd HH:mm:ss"):<bean:write name="today" format="yyyy-MM-dd HH:mm:ss"/>
<p>
<li>格式化数字</li><br>
n(default):<bean:write name="n"/><br>
n(format="###,###.####"):<bean:write name="n" format="###,###.####"/><br>
n(format="###,###.0000"):<bean:write name="n" format="###,###.0000"/><br>
<p>
<li>结构</li><br>
姓名:<input type="text" value="<bean:write name="user" property="username"/>"><br>
年龄:<input type="text" value="<bean:write name="user" property="age"/>"><br>
所属组:<input type="text" value="<bean:write name="user" property="group.name"/>"><br>
结果:
<logic:iterator>
request.setAttribute("userlist", userList);
<logic:notEmpty name="userlist">
<logic:iterate id="u" name="userlist">
<tr>
<td>
<bean:write name="u" property="username"/>
</td>
<td>
<bean:write name="u" property="age"/>
</td>
<td>
<bean:write name="u" property="group.name"/>
</td>
</tr>
</logic:iterate>
</logic:notEmpty>
进一步ActionForm
31_ActionForm_动态ActionForm.avi
1、动态ActionForm
动态ActionForm是为了避免标准ActionForm膨胀而设计的,使用动态ActionForm可以获得标准
ActionForm的所有功能
* 在struts-config.xml文件中定义动态ActionForm,如:
<form-beans>
<form-bean name="dynaForm" type="org.apache.struts.action.DynaActionForm">
<form-property name="username" type="java.lang.String" />
<form-property name="age" type="java.lang.Integer"/>
</form-bean>
</form-beans>
*在Action中使用动态ActionForm,参见DynaActionFormTestAction.java
DynaActionForm daf = (DynaActionForm)form;
String username = (String)daf.get("username");
Integer age = (Integer)daf.get("age");
动态ActionForm其实是把页面中的html元素的名字和值放到了map中,所以通过get方法可以取出相应的值
<form action="dyanactionform.do" method="post">
姓名:<input type="text" name="username"><br>
年龄:<input type="text" name="age"><br>
<input type="submit" value="提交">
</form>
动态ActionForm采用EL表达式的输出方式,${dynabean.map.prop}, 参见:dyna_actionform.jsp
用户名称:${dynaForm.map.username }<br>
年龄:${dynaForm.map.age }<br>
动态Action的验证,通常使用动态验证框架validator
32_ActionForm_Struts上传.avi
2、采用struts上传文件
l 页面的配置,如:
<form action="upload.do" method="post" enctype="multipart/form-data">
标题:<input type="text" name="title"><br>
文件:<input type="file" name="myfile"><br>
<input type="submit" value="提交">
</form>
l ActionForm中使用FormFile来接收上传的文件,参见:UploadActionForm.java
public class UploadActionForm extends ActionForm {
private String title;
private FormFile myfile; //必须采用FormFile
……
}
l 在Action中调用FormFile取得上传文件数据,采用流输出,即完成上传,参见:UploadTestAction.java
UploadActionForm uaf = (UploadActionForm)form;
FormFile myFile = uaf.getMyfile();
if (myFile != null) {
FileOutputStream fos = new FileOutputStream("c://" + myFile.getFileName());
fos.write(myFile.getFileData());
fos.flush();
fos.close();
}
l 在Struts-config.xml中配置采用<controller/>标签配置上传参数,如:<controller maxFileSize="10M"/>,一般采用
3、空字段测试
* 在表单中没有input输入域,jsp脚本接收到的值为null,el表达式接收到的值为空串
* 如果表单中的值,没有输入,那么jsp脚本和el表达式接收到的值都为空串
34_ActionForm_Struts类型转换器.avi
4、测试ActionForm类型的自动转换
(1) boolean:yes,1,on,true都会转换成True类型,而且忽略大小写,其他情况转换成false
(2) Date类型的转换:
* 如果是java.sql.Date,页面日期的格式必须为yyyy-mm-dd, 才可以转换,如果改为2008/03/31出错
* 如果是java.util.Date,默认情况下struts无法转换(需要自定义转换器)
(3) 自定义转换器的实现步骤
n 实现converter接口,实现convert方法
public class UtilDateConverter implements Converter {
public Object convert(Class type, Object value) {}
n 将实现的conerter注册,通常情况采用servlet注册(web.xml)
public class UtilDateConverterInitWithServlet extends HttpServlet {
public void init() throws ServletException {
System.out.println("UtilDateConverterInitWithServlet.init()");
//注册转换器
ConvertUtils.register(new UtilDateConverter(), Date.class);
}
<servlet>
<servlet-name>UtilDateConverterInitWithServlet</servlet-name>
<servlet-class>com.bjsxt.struts.UtilDateConverterInitWithServlet
</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
n 采用servlet注册需要注意标签的配置,<load-on-startup>10</load-on-startup>(也可以采用struts plugin注册(Struts-config.xml中))
public class UtilDateConverterInitWithPlugin implements PlugIn {
public void init(ActionServlet servlet, ModuleConfig config)
throws ServletException {
System.out.println("UtilDateConverterInitWithPlugin.init()");
ConvertUtils.register(new UtilDateConverter(), Date.class);
}
}
<plug-in className="com.bjsxt.struts.UtilDateConverterInitWithPlugin"/>
Struts对ActionForm的自动搜集过程:
* 将页面数据放到map中,其中map中的key为页面中的名称,map中的value为页面中的value值
* 调用BeanUtils.setProperties方法,将map中的值逐个设置到ActionForm实例上,对于ActionForm中的每个属性,根据类型调用相应的Converter,然后调用相应的convert方法,将相应的字符串转换成ActionForm中指定的类型
可以通过BeanUtils.copyProperties(目标对象,源对象)方法进行对象值的复制。
DTO数据传输对象 VO值对象
DTO==VO Actionform相当于DTO 是粗粒度的
尚学堂科技_王勇_JAVA视频教程_Struts11_ActionForward_ActionMapping_Action
36_ActionForward.avi
ActionForward的使用
1、理解全局和局部ActionForward的概念
全局的ActionForward所有的action都可以使用,Action现在自己的<forward>中查找,如果没找到,继续查找全局的actionforward(判断用户登陆与否,没登陆跳转到登陆页面,可以设成一个全局forward)
<global-forwards>
<forward name="login" path="/login.jsp" redirect="true"/>
</global-forwards>
2、redirect的使用
3、struts-config.xml文件不允许动态修改
在Action中一下代码会出异常
ActionForward af = mapping.findForward("login");
//struts-config.xml文件不能修改
af.setRedirect(false);
return af;
4、理解动态ActionForward,动态的ActionForward是可以运行期修改的
由于struts-config.xml文件不能动态修改,我们可以再action中自己构造一个ActionForwar
ActionForward af = new ActionForward();
af.setPath("/page" + page + ".jsp?name=Tom");
return af;
37_ActionMapping.avi
1、struts-config.xml文件中,每个<action>标签对应一个ActionMapping实例
2、了解<action>标签中的forward和unknown属性的含义
l forward属性:forward和type属性是互斥的,其中forward优先级高,如果同时配置了这两个属性,会直接转向到forward所指向的页面,而不会执行type定义的class;有时一个Action不做任何事情,只负责转向
这时,就可以在action中设置forward属性,而不用<forward>标签:
a href="login1.do">登录</a><br>
<action path="/login1"
forward="/login.jsp"
></action>
l uknown属性,实质上是一种容错处理。如果页面指向某个action,如xxxx.do,但在配置文件中找不到对应配置,那么就会在配置文件中查找某个unknown属性设为 true 的那个action,从而转向其设定的页面。一个struts-config.xml中只能配一个action的unknown属性为true
<action path="/testunknown"
unknown="true"
forward="/testunknown.jsp"
l ></action>
3、了解采用jstl和struts标签保持页面数据
41_JAVA国际化.avi
1、了解缺省Locale是由操作系统决定的,Locale是由语言和国家代码组成
2、国际化资源文件是由baseName+locale组成,如:MessageBundle_en_US.properties
baseName是任意合法的文件名;在系统中一般会提供一个缺省的资源文件(baseName.properties),当都找不到时,使用缺省的。
3、native2ascii命令的位置和用法
* 位置:JAVA_HOME/bin
* 使用native2ascii.exe o.properties MessagesBundle_zh_CN.properties
l 使用默认的,和操作系统一致
Locale defaultLocale = Locale.getDefault();
System.out.println("default country=" + defaultLocale.getCountry());
System.out.println("default language=" + defaultLocale.getLanguage());
ResourceBundle rb = ResourceBundle.getBundle("res.MessagesBundle", defaultLocale);
System.out.println(rb.getString("k1"));
System.out.println(rb.getString("k2"));
l 使用自己构造的,可以再系统中自己构造Locale
Locale currentLocale = new Locale("en", "US");
Locale currentLocale = new Locale("zh", "CN");
Locale currentLocale = new Locale("ja", "JP");
ResourceBundle rb = ResourceBundle.getBundle("res.MessagesBundle", currentLocale);
System.out.println(rb.getString("k1"));
System.out.println(rb.getString("k2"));
l 资源文件中,某些东西是运行时决定的,采用占位符的形式,如:MessagesBundle_en_US.properties中
k1=hello,{0}
k2=good bye
Locale currentLocale = new Locale("en", "US");
Locale currentLocale = new Locale("zh", "CN");
Locale currentLocale = new Locale("ja", "JP");
//ResourceBundle rb = ResourceBundle.getBundle("MessagesBundle", currentLocale);资源文件放在根目录下
ResourceBundle rb = ResourceBundle.getBundle("res.MessagesBundle", currentLocale);放在res目录下
System.out.println(rb.getString("k1"));
System.out.println(rb.getString("k2"));
MessageFormat mf = new MessageFormat(rb.getString("k1"));
System.out.println(mf.format(new Object[]{"Tom"}));
System.out.println(mf.format(new Object[]{"张三"}));
尚学堂科技_王勇_JAVA视频教程_Struts13_Struts及JSTL国际化
42_Struts硬编码国际化.avi
1、struts国际化的配置
* 在struts-config.xml文件中加入:<message-resources parameter="MessageResources" />
2、提供不同版本的国际化资源文件,中文需要采用native2ascii转换成unicode
3、在jsp中采用<bean:message>标签来读取国际化消息文本
<bean:message key="username"/>:<input type="text" name="username"><br>
<bean:message key="password"/>:<input type="password" name="password">
4、了解利用struts默认将locale放到session中的特性,完成采用编程的方式切换语言设置
* 参见:ChangeLanguageAction.java
Locale currentLocale = Locale.getDefault();
if ("zh".equals(lang)) {
currentLocale = new Locale("zh", "CN");
}else if("en".equals(lang)) {
currentLocale = new Locale("en", "US");
}
//request.getSession().setAttribute(Globals.LOCALE_KEY, currentLocale);//自己设置
this.setLocale(request, currentLocale);//struts中带的方法
return mapping.findForward("index");
5、消息文本的国际化处理,共有三个步骤:
* 创建国际化消息
* 传递国际化消息
* 显示国际化消息
public class LoginAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
LoginActionForm laf = (LoginActionForm)form;
String username = laf.getUsername();
String password = laf.getPassword();
ActionMessages messages = new ActionMessages();
try {
UserManager.getInstance().login(username, password);
//创建国际化消息文本,//动态消息用username填充{0}
ActionMessage message = new ActionMessage("user.login.success", username);
//ActionMessage message = new ActionMessage("user.login.success", new Object[]{username});
messages.add("loginSuccess1", message);
ActionMessage message1 = new ActionMessage("user.login.success", username);
messages.add("loginSuccess1", message1);
//传递国际化消息文本
this.saveMessages(request, messages);
return mapping.findForward("success");
}catch(UserNotFoundException unfe) {
unfe.printStackTrace();
//创建国际化消息文本
ActionMessage message = new ActionMessage("user.not.found", username);
messages.add("error1", message);
//传递国际化消息文本
this.saveErrors(request, messages);//错误提示消息
}catch(PasswordErrorException pee) {
pee.printStackTrace();
//创建国际化消息文本
ActionMessage message = new ActionMessage("user.password.error");
messages.add("error2", message);
//传递国际化消息文本
this.saveErrors(request, messages);
}
return mapping.findForward("error");
}
如何创建国际化消息?
理解ActionMessage和ActionMessages两个对象的区别
如何传递国际化消息?
* 调用saveMessages()传递普通消息,调用saveErrors传递错误消息
如何显示国际化消息?
通过<html:messages>标签显示消息(可以显示普通消息和错误消息),默认显示错误消息,将属性message=“true”显示普通消息
<html:messages id="msg" message="true" property="loginSuccess1">
<bean:write name="msg"/>
</html:messages>
Property起过滤作用,默认显示所有messages中的消息
通过<html:errors>显示消息(只能显示错误消息)
46_动态验证框架简介.avi
struts validator验证框架
1、配置:
* 加入国际化配置在struts-config.xml文件中,如:
<message-resources parameter="MessageResources" />
配置动态ActionForm---- DynaValidatorForm
<form-bean name="loginForm" type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="username" type="java.lang.String"/>
<form-property name="password" type="java.lang.String"/> </form-bean>
* 提供国际化资源文件
* 引入validator插件在struts-config.xml文件中,如:
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>
* 提供validation.xml和validator_rules.xml文件,将此文件拷贝到WEB-INF下
Validation.xml
<form-validation>
<formset>
<form name="loginForm">
<field property="username" depends="required">
<arg key="prompt.username"/>
</field>
<field property="password" depends="required,mask">
<arg key="prompt.password"/>
<var>
<var-name>mask</var-name>
<var-value>^[0-9a-zA-Z]*$</var-value>
</var>
</field>
</form>
</formset>
</form-validation>
2、validator服务器端验证
* 配置validation.xml文件
3、validator客户端验证(javascript)
) * 配置validation.xml文件
* 在jsp页面中包含< html:javascript>
* 对需要验证的表单定义onsubmit事件,其中事件名称为validate+ActionForm的名称,如:validateLoginForm
<html:javascript formName="loginForm"/>
<html:form action="login2.do" onsubmit="return validateLoginForm(this)">
username : <html:text property="username"/><br/>
password : <html:password property="password"/><br>
<html:submit/>
</html:form>
尚学堂科技_王勇_JAVA视频教程_Struts15_声明式异常及个性化异常
48_Struts声明式异常.avi
1、编程式异常
* 截获异常
* 创建相应的异常消息
* 传递异常消息
* 转向相应的页面处理异常
2、声明式异常(自动处理的异常)
* 在struts-config.xml文件中配置<exeception/>标签
* 理解局部和全局exception
* 注意局部<exception/>标签需要配置到<forward/>标签的前面,详见dtd中的约束
<action path="/login"
type="com.bjsxt.struts.LoginAction"
name="loginForm"
scope="request"
validate="false"
input="/login.jsp"//出现异常或validate验证失败后的转向页面
>
<!—局部异常
<exception key="user.not.found" type="com.bjsxt.struts.UserNotFoundException" path="/login_error.jsp"/>
<exception key="user.password.error" type="com.bjsxt.struts.PasswordErrorException" path="/login_error.jsp"/>path定义异常转向页面,如果action的input属性和这个path属性都配了,则path优先级高
-->
<forward name="success" path="/login_success.jsp"/>
<forward name="error" path="/login.jsp"/>
</action>
<global-exceptions>
<exception key="user.not.found" type="com.bjsxt.struts.UserNotFoundException" path="/login_error.jsp"/>
</global-exceptions>
<exeception/>标签中的属性说明:
* key:指异常信息对应的国际化消息文本,这个key值需要在国际化资源文件中定义
* type: 处理那种异常
* path: 定义一但出现异常,需要转向那个页面,如果不定义path,
默认情况下将使用<action>标签中input属性对应的页面
* scope:可以取值request和session,默认为request
* handler:异常的处理类,struts默认采用org.apache.struts.action.ExceptionHandler,
如果做个性化的异常处理可以继承此类覆写相应的方法
参见:ErrorCodeExceptionHandler.java和AppExceptionHandler.java
51_DispatchAction.avi
采用DispathAction
* 如果覆写DispathAction中的execute方法,必须显示的用super调用execute方法
public class UserAction extends DispatchAction {
……
public ActionForward add(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
}
public ActionForward del(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
}
}
* parameter参数值不能是execute或perform
<action path="/user/usermaint"
type="com.bjsxt.drp.web.usermgr.actions.UserAction"
name="userForm"
scope="request"
parameter="command"
>
……
</action>
* 了解<action>标签中的parameter的含义
相应的jsp页面的action属性必须设为usermaint.do?command=add
* 了解DispathAction中的unspecified方法的含义
//可以利用这个方法进行容错处理,当路径找不到时,进行处理
protected ActionForward unspecified(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
throws Exception {
}
52_Struts模式匹配.avi
减少配置量
一.Action类
public class UserAction extends DispatchAction {
public ActionForward add(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
return mapping.findForward("success");
}
public ActionForward del(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
return mapping.findForward("success");
}
public ActionForward modify(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
return mapping.findForward("success");
}
}
二.Index.jsp
<a href="user/add.do?command=add">添加用户</a><br>
<a href="user/del.do?command=del">删除用户</a><br>
<a href="user/modify.do?command=modify">修改用户</a><br>
三.struts-config.xml
<action path="/user/*"
type="com.bjsxt.struts.UserAction"
parameter="command"
>
<!--
<forward name="success" path="/user/{1}_success.jsp"/>
-->其中解析{1}=add | del |modify
<forward name="success" path="/{0}_success.jsp"/>
</action>其中解析{0}=user/add | user/del |user/modify