1.web应用的访问过程
请求到服务器比如:http://localhost:8089/struts2/index web容器会首先找到相应的应用(这里就是struts2)的web.xml,而在struts2中的web.xml的一般配置为:
<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>/*</url-pattern>
</filter-mapping>
那么根据这个过滤器,所有请求都会去找org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter这个类去处理,而这个类的功能就是根据class下面的struts.xml对请求进行“分配”。
2.struts.xml中的package属性和action属性
定义格式为:
<package name="main" extends="struts-default" namespace="/path">
<action name="path" class="com.struts2.front.action.PathAction">
<result name="path">
/path.jsp
</result>
</action>
</package>
package中需要注意的是namespace这个属性,它定义了该package处理的路径,如namespace="/",那么访问http://localhost:8089/xxx的页面都会到这个package下面来找相应的action xxx,如果配置的/path(正如上面的例子)那么只有访问http://localhost:8089/path/abc的请求才会到该package下面找相应的action。
注意:
1.如果不写namespace或者写namespace="",那么该package会处理所有目录下的action
2.如果struts2找不到对应的namespace和action处理,就会将请求交给tomcat处理
3.struts2中的jsp页面尽量使用绝对路径,相对路径可能产生相应的问题
定义绝对路径的方法:
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<base href="<%=basePath%>">
<a href="index.jsp">index.jsp</a>
只要设置了base后,所有href的内容前面都会自动加上base
总结:namespace这个属性决定了什么样的请求才会到这个package中寻找action
action属性:
action的name属性表示了该package所能处理的请求,action的class属性表示当用户访问该action时候使用哪个类处理,action的method属性定义了使用这个类的哪个方法处理该请求。如果不写,那么默认会调用该类中的execute()方法。 所以如果不指定method,那么必须在类中实现public String execute()方法。如果不指定类,那么struts2会自己调用com.opensymphony.xwork2.ActionSupport中的execute()方法,这个方法返回success。
struts2每次请求的时候都会new一个新的action类,这点跟struts1是不一样的,struts1每次都使用同一个action类,所以可能出现线程同步之间的问题。
action类的写法有3种:
1.自己定义一个类,然后定义method中指定的所有方法
2.实现Action接口 -----这个接口只是有一个public String execute()方法
3.继承自ActionSupport类
第3种方法是最常用的方法,因为ActionSupport类中提供了我们常用的功能。
而寻找action中调用的方法也有3种方法:
<1>定义method属性<2>使用action名称之后加!+方法名<3>使用通配符
也可以不在action中指定method而通过url中在action名称之后加上一个!+方法名来指定使用的方法,如:http://localhost:8089/struts2/user!add struts2就会找到user这个action的方法add对这个请求进行相应。
使用通配符指定方法名,如:
<action name="Student*" class="com.struts2.front.action.StudentAction" method="{1}">
<result>/Student{1}_success.jsp</result>
<result name="login">/Student{1}_login.jsp</result>
</action>
这种很好用啊很好用,甚至在所有名称都符合约定的时候可以只写一个action来处理所有请求。
可见,约定优于配置。
还有高级点的配置方法
<package name="main" extends="struts-default" namespace="">
<action name="*_*" class="com.struts2.front.action.{1}Action" method="{2}">
<result>/{1}{2}_success.jsp</result>
</action>
</package>
3.用action属性接收参数的3中方法
1>在自己的action中定义属性,写好get和set方法,然后就可以直接使用了(struts2自动调用set方法,可以写成int类型,struts2会自动转型)
public class StudentAction extends ActionSupport{
private String name;
private int age;
public String test(){
System.out.println("name: " + name);
System.out.println("age: " + age);
return ActionSupport.SUCCESS;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
访问的url类似http://localhost:8089/struts2/path/Student_test?name=zhangsan&age=29
2>使用DomainModel action中直接使用一个person,而person来自于model包,也就是域模型,不要忘记了getPerson()和setPerson()方法,不用自己new Person
public class StudentAction extends ActionSupport{
private Person person;
public String test(){
System.out.println("name: " + person.getName());
System.out.println("age: " + person.getAge());
return ActionSupport.SUCCESS;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
访问的url类似:http://localhost:8089/struts2/path/Student_test?person.name=caocao&person.age=29
多的参数接收不到,少的参数会使用默认值,可以使用PersonDTO来解决问题,也就是使用一个中间的model对象来处理数据。
3.modeldrivernparamInput action实现一个接口ModelDriven (不常用,但是体现mvc特性)
这种方式person必须得自己new
public class StudentAction extends ActionSupport implements ModelDriven<Person>{
private Person person = new Person();
public String test(){
System.out.println("name: " + person.getName());
System.out.println("age: " + person.getAge());
return ActionSupport.SUCCESS;
}
public Person getModel() {
return person;
}
}
访问的url类似:http://localhost:8089/struts2/path/Student_test?person.name=liubei&person.age=30