今天重要开始web三大框架的struts2学习了,心情还是激动的,赶快今天的学习吧。
struts2
是流行和成熟的基于mvc的设计模式的web应用程序框架。
mvc
mvc =jsp+servlet+javabean
mvc流程
struts2.0发展历史
struts2.0环境搭建
Struts使用
在myeclipse中集成了struts,可以自动创建,这个方法非常简单,建议使用。在其他地方使用,需要去官网下载导入对应的jar,然后在web.xml
配置Filter,在创建struts.xml,两种方法都是一样的。
配置完成之后,在项目中主要有这两个地方变化:
web.xml
<filter>
<filter-name>struts</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
</struts>
struts 工作原理
客户通过request请求,经过一系列过滤器,这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助。FilterDispatcher这个过滤器已经过时了,采用StrutsPrepareAndExecuteFilter,为啥用这个,FilterDispatcher无法实现,在action之前实现自己定义过滤器。只有action为后缀的,才会走到ActionMapper,决定是否调用action。然后在回到StrutsPrepareAndExecuteFilter,ActionProxy代理器通过configurationmanager,来读struts.xml,找到对应的action类。通过ActionProxy创建反向实例,通过一系列拦截器,返回字符串result,在经过一系列的拦截器,然后通过resoponse返回到用户实例。
struts核心文件
struts.xml
- 全局属性
- 用户请求和响应action之间对应关系
- action可能用到的参数和返回结果
- 各种拦截器的配置
struts访问servle的Api
- 通过ActionContext
- 实现xxx.aware接口
- 通过ServletActionContext
Struts2框架提供了一种更轻松的方式来访问Servlet API。Struts2中提供了一个ActionContext类(当前Action的上下文对象),通过这个类可以访问Servlet API。下面是该类中提供的几个常用方法:
l public static ActionContext getContext() :获得当前Action的ActionContext实例。
l public Object get(Object key) :此方法类似于调用HttpServletRequest的getAttribute(String name)方法。
l public void put(Object key, Object value) :此方法类似于调用HttpServletRequest 的setAttribute(String name, Object o)。
l public Map getParameters() :获取所有的请求参数。类似于调用HttpServletRequest对象的getParameterMap() 方法。
l public Map getSession() :返回一个Map对象,该Map对象模拟了HttpSession实例。
l public void setSession(Map session) : 直接传入一个Map实例,将该Map实例里的key-value对转换成session的属性名-属性值对。
l public Map getApplication() :返回一个Map对象,该对象模拟了该应用的ServletContext实例。
l public void setApplication(Map application) :直接传入一个Map实例,将该Map实例里的key-value对转换成application的属性名-属性值对。
该有一个更简单的方法,就是通过ServletActionContext
struts第一个简单例子
jsp页面
<form action="LoginAction.action" method="post">
用户名:<input type="text" name="username"/>
密码:<input type="password" name="userpass"/>
<input type="submit" value="提交"/>
</form>
form标签中action属性,指定提交之后的跳转的action。
创建action
public class LoginAction extends ActionSupport {
public String Login() {
// TODO Auto-generated method stub
return SUCCESS;
}
action需要继承ActionSupport,这里是自己定义的方法,故需要在strurs.xml配置method属性,如果重写ActionSupport父类的excute,则在action配置时,不需要单独指明method。特别需要注意的地方,在自定义实现action的方法,必须将方法的修饰符,定义为public,否则会报错。
struts.xml配置
<package name="default" namespace="/" extends="struts-default">
<action name="LoginAction" method="Login" class="com.example.action.LoginAction">
<result name="success">/scuess.jsp</result>
</action>
</package>
先申明struts标签下的package属性,基本都是这种配置,然后配置自己的action,name属性就用自己action类的名字,method属性,如果在action没有重写excute,需要指定,否则不要。
struts搜索顺序
动态执行action的方法
在一般中执行action只有一个请求处理方法,就是excute,为此我们可以在一个action调用多个方法:
- 在struts.xml中的action配置method属性,但是这样还是有缺点,需要配置多个action。
<action name="LoginAction" method="Login" class="com.example.action.LoginAction">
- 官方推荐通配
<action name="LoginAction_*" method="{1}" class="com.example.action.LoginAction">
<result name="success">/scuess.jsp</result>
<result name="add">/{1}.jsp</result>
<result name="fail">/{1}.jsp</result>
- 自己配置result
<result name="add">/scuess.jsp</result>
<result name="fail">/scuess.jsp</result>
public String Login() {
// TODO Auto-generated method stub
System.out.println(user.getUsername()+"lallalalala");
System.out.println(user.getUserpass()+"hsdhasdasdas");
return "add";
}
指定多个配置文件
指定多个struts.xml,按项目功能的配置,进行汇总到一个总的struts.xml。
在struts,xml用 <include>标签引入。
默认action
输入错误的url,找不到action,如果不采用默认action处理,直接报网页错误,用户体验会很差。由此出现默认action,通过在struts.xml配置<default-action-ref>标签。
<default-action-ref name="index"></default-action-ref>
<action name="index">
<result>/scuess.jsp</result>
</action>
name属性,必须一致。
action后缀
我们在请求处理action的时候,会判断action的后缀,是通过struts.xml<struts.action.extention>标签配置。
<constant name="struts.action.extension" value="action,do,html"></constant>
如果value没有值,就表示action请求可以没有后缀。
struts接收参数方式
- 使用action属性
通过,在action定义表单控件name相同的属性,并且提供相应的setter、getter。在action就可以直接从表单的参数值了。
<form action="LoginAction.action" method="post">
用户名:<input type="text" name="username"/>
密码:<input type="password" name="userpass"/>
<input type="submit" value="提交"/>
</form>
private String username;
private String userpass;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserpass() {
return userpass;
}
public void setUserpass(String userpass) {
this.userpass = userpass;
}
public String Login() {
// TODO Auto-generated method stub
System.out.println(username+"lallalalala");
System.out.println(userpass+"hsdhasdasdas");
return SUCCESS;
}
- 使用DomainModel
按照上述的方法,如果参数多,就会不方便。这个方法主要是通过面向对象的思想,构建一个javabean,来实现。
public class User {
private String username;
private String userpass;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserpass() {
return userpass;
}
public void setUserpass(String userpass) {
this.userpass = userpass;
}
}
public class LoginAction extends ActionSupport {
private User user;//需要提交javabean对象的setter、getter方法
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String Login() {
// TODO Auto-generated method stub
System.out.println(user.getUsername()+"lallalalala");
System.out.println(user.getUserpass()+"hsdhasdasdas");
return SUCCESS;
}
}
<form action="LoginAction.action" method="post">
用户名:<input type="text" name="user.username"/>//需要指定对象的属性
密码:<input type="password" name="user.userpass"/>
<input type="submit" value="提交"/>
</form>
- 使用ModelDriven
主要通过action类实现ModelDriven接口,该方法也是最简便的。
public class LoginAction extends ActionSupport implements ModelDriven<User> {
private User user = new User();
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String Login() {
// TODO Auto-generated method stub
System.out.println(user.getUsername()+"lallalalala");
System.out.println(user.getUserpass()+"hsdhasdasdas");
return "add";
}
@Override
public User getModel() {
// TODO Auto-generated method stub
return user;
}
action的result类型
input:主要定义参数类型错误的result,在action重写下面方法,出现错误即会跳转对应的input页面
@Override
public void validate() {
// TODO Auto-generated method stub
if(user.getUsername().equals("")){
this.addFieldError("user", "用户名不能为空");
}
}
result处理结果类型
- 局部结果,将result标签作为action标签的子标签。
- 全局结果,将result标签作为global-result的子标签。比如定义404,500错误。