Struts2

第一个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的工作原理及文件结构:




核心文件:

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的用法:


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.处理结果类型



<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返回网页源代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值