Struts2

来源:互联网 发布:ubuntu 限制root登录 编辑:程序博客网 时间:2024/06/17 12:34
第一个Struts2程序:
MyEclipse:
1.新建一个web project,右键添加支持选择install  ApacheStruts (2.x) Facet
web.xml和struts.xml文件都已经创建完成了。


Eclipse:
1.下载相关jar包(2.3.24)
http://struts.apache.org/

2.创建web项目
Dynamic web project
添加以下jar包    

Struts2


配置web.xml文件:
《display-name》HelloWorld《/display-name》
  《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》       
  《welcome-file-list》
   《welcome-file》index.jsp《/welcome-file》
  《/welcome-file-list》
《/web-app》

创建一个继承自ActionSupport的类并添加方法:
public class HelloWorldAction extends ActionSupport {
@Override
public String execute() throws Exception {
System.out.println("执行action");
return SUCCESS;
}
}

创建struts.xml文件:
《?xml version="1.0" encoding="UTF-8"?》
《!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd"》
《struts》
《package name="default" namespace="/"extends="struts-default"》
《action name="helloworld"class="com.imooc.action.HelloWorldAction"》
《result 》/result.jsp《/result》
《/action》
《/package》
《/struts》
创建result.jsp,输出this is result.jsp

debug as--》debug onserver,然后再运行http://j1vb4cxmg7wmrpp:8080/HelloWorld/helloworld.action

界面跳转到result.jsp,控制台输出执行action。





Struts2的工作原理及文件结构:

Struts2
Struts2


核心文件:
web.xml
任何MVC框架都需要与Web应用整合,这就不得不借助于web.xml文件,只要配置在web.xml文件中Servlet才会被应用加载。
通常,所有的MVC框架都需要Web应用加载一个核心控制器,对于Struts2框架而言,需要加载StrutsPrepareAndExecuteFilter,只要web应用负责加载StrutsPrepareAndExecuteFilter,StrutsPrepareAndExecuteFilter将会加载Struts2框架。

struts.xml
struts2的核心配置文件,在开发过程中利用率最高。该文件主要负责管理应用中的action映射,以及该action包含的result定义等。
struts.xml中包含的内容:
1.全局属性
2.用户请求和相应action之间的对应关系
3.action可能用到的参数和返回结果
4.各种拦截器的配置

struts.properties
struts2框架的全局属性文件,自动加载。与struts.xml防在一个位置
该文件包含很多key-value对。
该文件完全可以配置在struts.xml文件中,使用constant元素。
Struts2



深入Struts2的用法:

struts.xml,struts.properties具体


Struts2提供了三种方式去访问Servlet API。
1.ActionContext
2.实现***Aware接口
3.ServletActionContext


Action搜索顺序:
action的搜索机制:
http://localhost:8080/struts2/path1/path2/path3/student.action
第一步:判断package是否存在,如:path1/path2/path3/
存在:
判断action是否存在,如果action不存在则去默认namespase的package里面寻找action,如果没有,则报错。
不存在:检查上一级路径的package是否存在(直到默认namespace,重复第一步),如果没有则报错。







动态方法调用:
动态方法调用就是为了解决一个action对应多个请求的处理,以免action太多。
指定method属性:
在HelloWorldAction.java中添加一个方法
public String add(){
return SUCCESS;
}
然后要在struts.xml文件中进行配置该方法:
《action name="addAction" method="add"class="com.imooc.action.HelloWorldAction"》
《result 》/add.jsp《/result》
《/action》
然后访问:http://localhost:8080/HelloWorld/addAction.action

感叹号方式:
修改方法:
public String add(){
return "add";
}
在struts.xml中添加语句:
《constant name="struts.enable.DynamicMethodInvocation"value="true"》《/constant》
之后可以直接在helloworld的action标签中添加一个:
《result name="add"》/add.jsp《/result》  add为add方法的返回内容。
访问:http://localhost:8080/HelloWorld/helloworld!add.action

通配符方式(官方推荐使用):
《struts》
《package name="default" namespace="/"extends="struts-default"》
《action name="helloworld_*" method="{1}"class="com.imooc.action.HelloWorldAction"》  星号就是method中数字的值
《result 》/result.jsp《/result》
《result name="add"》/{1}.jsp《/result》
《/action》
《/package》
《constant name="struts.enable.DynamicMethodInvocation"value="false"》《/constant》   修改false
《/struts》 
访问:http://localhost:8080/HelloWorld/helloworld_add.action

更为通用的方式:(即第一个星号等于{1},第二个星号表示{2})
《action name="*_*" method="{2}"class="com.imooc.action.{1}Action"》
《result 》/result.jsp《/result》
《result name="add"》/{2}.jsp《/result》
《/action》
http://localhost:8080/HelloWorld/HelloWorld.action进入result.jsp
http://localhost:8080/HelloWorld/HelloWorld_add.action进入add.jsp





指定多个配置文件:
如果一个项目中有成千上万个action,那么我们就需要在一个struts.xml中配置很多的action,这样struts.xml就会非常大。为了解决这个问题,我们可以指定多个配置文件。
将struts.xml更改为:
《struts》
《include file="helloworld.xml"》《/include》
《constant name="struts.enable.DynamicMethodInvocation"value="false"》《/constant》
《/struts》

然后创建一个新的helloworld.xml文件:
《?xml version="1.0" encoding="UTF-8"?》
《!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd"》
《struts》
《package name="default" namespace="/"extends="struts-default"》
《action name="*_*" method="{2}"class="com.imooc.action.{1}Action"》
《result 》/result.jsp《/result》
《result name="add"》/{2}.jsp《/result》
《/action》
《/package》
《/struts》
这样就能够实现多个配置文件。
如果出现了编码问题,我们可以在每个配置文件中添加:
《constant name="struts.i18n.encoding" value="UTF-8"》《/constant》




默认action:
《default-action-ref name="index"》《/default-action-ref》
《action name="index"》
《result 》/error.jsp《/result》
《/action》
《action name="*_*_*" method="{2}"class="com.imooc.{3}.{1}Action"》      这里修改了*的数量
《result 》/result.jsp《/result》
《result name="add"》/{2}.jsp《/result》
《/action》

当访问错误的例如:http://localhost:8080/HelloWorld/agddd.action
会返回error.jsp——》Sorry,Not Found This Path.

只有输入正确的:http://localhost:8080/HelloWorld/HelloWorld_add_action.action






Struts2的后缀:
当不进行任何配置的时候,访问HelloWorld_add_action.action和HelloWorld_add_action都能到add.jsp页面。
3种方式:
1.当在struts.xml文件中添加:
《constant name="struts.action.extension"value="html"》《/constant》
这样就只能访问:HelloWorld_add_action.html

这种配置方式还可以在value中通过英文的,号添加多个:
value="action,do,struts2"

2.另一种配置方式是在struts.properties中配置:
struts.action.extension=action,do,struts2

3.在过滤器《filter》中配置intt-param参数:
《init-param》
《param-name》struts.action.extension《/param-name》
《param-value》do,action,strtus2《/param-value》
《/init-param》






接受参数:
1:使用Action的属性接收参数
首先新建一个login.jsp界面:
 由于前面已经该过后缀
  用户名:《input type="text"name="username"》
  密码:《input type="password"name="password"》
  《input type="submit" value="提交"/》
 
然后新建一个LoginAction.java:
public class LoginAction extends ActionSupport {
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
private String username;
private String password;
public String login(){
System.out.println(username);
return SUCCESS;
}
}
之后在配置文件的pageage中配置一下:
《action name="LoginAction" method="login"class="com.imooc.action.LoginAction"》
《result 》/success.jsp《/result》
《/action》
新建一个简单的success.jsp界面。
运行服务器,登录到login界面输入用户名和密码,跳转到success界面,后台输出用户名。
2:使用Domain Model接收参数
添加一个类:
public class User {
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
private String username;
private String password;
}
修改最开始LoginAction.java
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
private User user;
public String login(){
System.out.println(user.getUsername());
return SUCCESS;
}
修改login.jsp:
用户名:《input type="text" name="user.username"》
密码:《input type="password" name="user.password"》
运行结果和1中类似。
这样引入了Model的概念,可以处理接受数量巨大的参数。



3:使用ModelDriven接收参数
为LoginAction.java添加接口:
public class LoginAction extends ActionSupport implementsModelDriven《User》{
private User user = new User();
public String login(){
System.out.println(user.getUsername());
return SUCCESS;
}
@Override
public User getModel() {
return user;
}
}
更改login.jsp中的属性:
用户名:《input type="text" name="username"》
密码:《input type="password" name="password"》
会得到同样的结果。
由此可以看出,如果我们采用第三种方法会省去很多麻烦。

复杂数据类型的接受:
1.list
在User类中添加private List《String》 booklist以及它的get和set方法。
在login.jsp中添加:
书籍1:《input type="text" name="booklist[0]"》
书籍2:《input type="text" name="booklist[1]"》
在LoginAction.java中的login方法中添加:
System.out.println(user.getBooklist().get(0));
System.out.println(user.getBooklist().get(1));
这样就会在输入书籍1和书籍2提交后,在后台输出。

2.一个Model类
创建一个新类Book(包括2个属性:bookname和bookprice以及它们的get和set方法)
修改User:
private List《Book》 booklist;
public List《Book》 getBooklist() {
return booklist;
}
public void setBooklist(List《Book》 booklist) {
this.booklist = booklist;
}
修改login.jsp:
书籍1名称:《input type="text" name="booklist[0].bookname"》
书籍1价格:《input type="text"name="booklist[0].bookprice"》 
书籍2名称:《input type="text" name="booklist[1].bookname"》
书籍2价格:《input type="text" name="booklist[1].bookprice"》
修改LoginAction.java中的login方法:
System.out.println(user.getBooklist().get(0).getBookname());
System.out.println(user.getBooklist().get(1).getBookprice());
这样在输入提交之后,就会输出用户名,书籍1名称,书籍2价格。



关于input输入错误的处理:
现在配置的action--LoginAction中添加一个:
《result name="input"》/login.jsp《/result》  input出错返回到login.jsp
然后再输入的时候如果将书籍的价格输入成字符串的话,那么就会重新返回到login界面重新输入。
但这样并没有提示错误:
在login方法中添加:
if(user.getUsername()==null||"".equals(user.getUsername())){
this.addFieldError("username", "用户名不能为空!");
return INPUT;
}
然后再login.jsp中添加:
首部:《%@ taglib prefix="s" uri="/struts-tags"%》
在用户名行后面:《s:fielderror name="username"》《/s:fielderror》
这样运行之后,如果不输入用户名就进行提交,会重新回到login.jsp界面并报“用户名不能为空!”。

或者直接在LoginAction.java添加Override/Implement Methods:
@Override
public void validate() {
if(user.getUsername()==null||"".equals(user.getUsername())){
this.addFieldError("username", "用户名不能为空!");
}
}
login.jsp做同样的操作,效果一致。


8.处理结果类型
Struts2

《result name="success"》/success.jsp《/result》
result元素中name就是result元素的逻辑视图名称。
《result》/success.jsp《/result》
如果省略了name属性,系统将采用默认的name属性值,默认的name值是success。

处理结果是通过在struts.xml使用《result/》标签配置结果。
根据位置的不同,分为两种结果:
局部结果:
将《result/》作为《action/》元素的子元素配置。
全局变量:将《result/》作为《global-result/》元素的子元素配置


《result》拥有两个子标签:
1.location:该元素定义了该视图对应的实际视图资源。
2.parse:该参数指定是否可以在实际视图名字中使用OGNL表达式。(Struts2默认的OGNL是true)

关于OGNL:(修改后缀为action)
《result name="add"》
《param name="location"》/${#request.path}.jsp《/param》
《param name="parse"》true《/param》  (默认就是true,这里可以不写)
《/result》

再在之前的HelloWorldAction的add方法中添加:
private HttpServletRequest request;
request.setAttribute("path", "update");
访问:http://localhost:8080/HelloWorld/HelloWorld_add_action.action同样可以访问到add.jsp界面。


type属性:
《result name="success" type=""》/success.jsp《/result》
type的默认值为dispatcher,这个类型支持jsp视图技术。
struts2支持多种视图技术,例如JSP,Valocity,FreeMarker等。在使用其他视图技术的时候才有必要设置type的属性。
type其中的一些值:
chain定义从action到action的映射
redirect重定向
stream返回inputstream用于文件上传下载
plaintext返回网页源代码
0 0