ssh框架-Struts2(一)
Struts2
概述
用我们自己的话来说: struts是web层框架, 相当于Servlet
作用: 1. 获得请求参数 2. 调用业务 3. 分发转向
常用的WEB层框架

Struts2入门
1.环境下载
下载地址
http://struts.apache.org/download.cgi;

2. 导入jar
struts的jar比较多,可以从Struts官方提供的demo中拿到必要的jar就行. 在apps/struts2-blank项目下
3. 编写Action类
新建一个类,里面定义一个方法
/**
*一,创建了一个普通的类 ,定义了一个execute()方法
*好比我们之前:创建了一个ProductServlet,然后创建了一个doGet()方法一样
*二, 配置Action 好比配置Servlet一样,只不过不在web.xml里面配置,自己整了一套
* 在src目录下struts.xml的文件里面配置
*/
public class ActionDemo {
public void execute(){
System.out.println("收到到了请求...");
}
}
4. 配置struts.xml文件
在src底下新建一个xml 名称为 struts.xml. 在struts.xml里面配置action
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="test" extends="struts-default" namespace="/">
<!--一个请求对应一个Servlet, struts2里面一个请求配置一个Action -->
<action name="demo" class="demo.web.ActionDemo"></action>
</package>
</struts>
注意:
struts.xml文件名不可随意取,必须叫做struts.xml
struts.xml必须放在src类路径下
到struts的核心包中可以找到struts-2.3.dtd文件(建议配置本地的dtd,没网情况下也可以使用...)
5. 前端控制器配置
在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>
其实就是在web.xml中配置struts2的filter
6. 编写访问路径,进行测试
http://localhost:8080/Struts2/demo
三,Struts.xml中的配置详解
Eg
<struts>
<!--一,package指的就是一组请求的集合.(eg: 一个模块就创建一个package)
name属性: package的名字, 不要重复就好
extends属性: 继承的意思;当前我们自己的test包继承了struts-default这个包, 也就意味着test包拥有struts-default这个包定义的功能
namespace属性: 名称空间; 用意在于访问Action的时候加了一层路径
eg: 当前配置的是 / , 路径 http://localhost:8080/Struts2/demo01
当前配置的是 /test , 路径 http://localhost:8080/Struts2/test/demo01
abstract属性: 抽象的意思; 如果设置了为ture, 表明当前包没有实际用途,被别的包继承
-->
<package name="test" extends="struts-default" namespace="/">
<!--二. 一次请求就配置定义一个action标签
name属性: action的名字,说白了就是当前Action的访问路径. (不要重复)
class属性: 当前Action类的全限定名
method属性: 处理当前请求的方法名(说白了就是Action类里面的方法名),默认执行execute
-->
<action name="demo01" class="demo.web.ActionDemo01"></action>
<action name="fun02" class="demo.web.ActionDemo01" method="login">
<!--三, 通过 result配置结果(分发转向)
name属性: 结果的名字.说白了就是处理当前请求方法的返回值
type属性: 配置跳转的类型,默认是转发到页面(明天讲)
值: 就是跳转的路径.
-->
<result name="loginSuccess">
/login.jsp
</result>
</action>
</package>
</struts>
<struts>
<!--一,package指的就是一组请求的集合.(eg: 一个模块就创建一个package)
name属性: package的名字, 不要重复就好
extends属性: 继承的意思;当前我们自己的test包继承了struts-default这个包, 也就意味着test包拥有struts-default这个包定义的功能
namespace属性: 名称空间; 用意在于访问Action的时候加了一层路径
eg: 当前配置的是 / , 路径 http://localhost:8080/day42A_Struts2/demo01
当前配置的是 /test , 路径 http://localhost:8080/day42A_Struts2/test/demo01
abstract属性: 抽象的意思; 如果设置了为ture, 表明当前包没有实际用途,被别的包继承
-->
<package name="test" extends="struts-default" namespace="/">
<!--二. 一次请求就配置定义一个action标签
name属性: action的名字,说白了就是当前Action的访问路径. (不要重复)
class属性: 当前Action类的全限定名
method属性: 处理当前请求的方法名(说白了就是Action类里面的方法名),默认执行execute
-->
<action name="demo01" class="com.itheima.web.ActionDemo01"></action>
<action name="fun02" class="com.itheima.web.ActionDemo01" method="login">
<!--三, 通过 result配置结果(分发转向)
name属性: 结果的名字.说白了就是处理当前请求方法的返回值
type属性: 配置跳转的类型,默认是转发到页面(明天讲)
值: 就是跳转的路径.
-->
<result name="loginSuccess">
/login.jsp
</result>
</action>
</package>
</struts>
1.package标签
1.1概述
一个package就是一组业务的集合, 也就是说一个模块对应一个package . 举个例子 : 我们针对用户的操作有很多请求 . 用户的添加 、 用户的删除 、用户的修改...
1.2属性解释
name属性:package的名字,一般不建议重复
extends属性: 这个package 继承指定的package 。 struts-default 这也是一个package 这里面包含了很多的拦截器, 一般我们都会使用到这些拦截器。
namespace属性:翻译过来是命名空间 用意就是在根目录下面再加一个子路径才能访问到action。
如果namespace值是/, 通过localhost:8080/项目名/add来访问
如果namespace值是/user, 通过localhost:8080/项目名/user/add来访问
好处: 在写请求路径的时候,意思更加明确,看路径就可以确定对应是哪个模块abstract:抽象。用来被其他package继承的
2.action标签
2.1概述
一个动作就是一个Action ,通俗一点就是一个请求在xml配一个Action 。和以前的一个请求配一个Servlet 相似
2.2 属性解释
name: 配置action的访问名称, 一般就写 方法名、这个动作的名称。
class: 配置关联的action类的全限定名
method: action类中的方法名称,访问此action时调用的action类中的方法
-
如果namespace值是/, 通过localhost:8080/项目名/add来访问
如果namespace值是/user, 通过localhost:8080/项目名/user/add来访问
好处: 在写请求路径的时候,意思更加明确,看路径就可以确定对应是哪个模块
-
3.Result标签
3.1概述
result标签用于返回action处理请求的结果。 一般可以跳转jsp页面也可以再跳转到其他的action。
3.2属性解释
name: 视图名字,对应的是Action类中执行的方法的返回值。
type: 响应给浏览器的类型.(默认是转发到页面)
四,Action进阶
1,Action规范和特点
1.1Action的编写规范
action类需要提供无参构造函数
action中方法规定
修饰符:方法的修饰符必须是public
参数列表:方法必须是无参方法
返回值类型:String(目的在于响应)
1.2.action多例性【重点】
每次url访问时,action的实例就会被创建一次。action类是多实例的。
2.Action的通用写法
2.1普通类
这种方式就是我们最开始给大家写的, 就是一个普通类,然后里面写一个方法,具有String类型返回值即可。
2.2实现Action接口
好处是 : 我们少写一点代码, 可以使用接口里面定义的常量 SUCCESS \ ERROR ....
public class HelloWorld02 implements Action{
@Override
public String execute() throws Exception {
System.out.println("hi struts");
return SUCCESS;
}
}
2.3继承ActionSupport【重点】
这种做法,相比较前面的好处在于, ActionSupport 虽然是实现了Action的接口 , 但是内部自己也扩展了些功能 :eg: 提供了信息的校验、并且能够根据校验的结果回到原来的页面。如 : 它里面也集成了获取国际化资源的方法,我们可以直接使用。
Java代码
-
public class ActionDemo03 extends ActionSupport { @Override public String execute() throws Exception { System.out.println("ActionDemo03 execute()..."); return SUCCESS; } }
-
3.Action访问的路径配置
3.1通过method属性访问【重点】
一般来讲,我们的action类都不会只有一个execute方法,如果存在很多的方法 ,我们如何在struts.xml 里面映射到方法里面去呢? struts提供的第一种方法是在action里面使用method属性来指定访问的具体的方法。 举例如下:
<action name="user_login" class="demo.web.UserAction" method="login"></action> <action name="user_regist" class="demo.web.UserAction" method="regist"></action> <action name="user_active" class="demo.web.UserAction" method="active"></action> <action name="user_loginout" class="demo.web.UserAction" method="logout"></action>
这样看上去是挺好的。 直接指定method ,就会找到具体的方法。 但是如果以后我们的方法很多,这样就要配置很多的action标签了。这就不太好维护了。代码先就显得很多,所以这种方式用的不多.
3.2通过通配符访问【重点】
通配符的访问其实还是要依赖于method的属性,只不过在匹配来访的地址 和 action的名称的时候使用通配符来匹配。采取method属性访问的方式,一个请求需要写一个Action, eg:
<action name="user_login" class="demo.web.UserAction" method="login"></action> <action name="user_regist" class="demo.web.UserAction" method="regist"></action> <action name="user_active" class="demo.web.UserAction" method="active"></action> <action name="user_loginout" class="demo.web.UserAction" method="logout"></action>
如果采取通配符的方式,只需要配置一个Action就可以了, *用于表示匹配任意字符。 后面的{1} 就表示能够取到 * 所处位置的字符,然后找到对应的方法。
<action name="user_*" class="demo.web.UserAction" method="{1}"></action>
我们在开发中通常采取通配符方式访问.
3.3通过动态方法访问【了解】
第三种方式可读性不强 ,这种方式使用动态代理访问。用的很少. 使用步骤:
打开动态访问开关,在Struts.xml文件配置
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
2.配置Action的名字
<action name="userAction" class="com.itheima.web.UserAction"></action>
3.访问路径通过actionName + !+ action类中的方法名访问
http://localhost:8080/Struts2/userAction!login
五.Result结果配置
1.全局和局部结果
平常我们设置跳转页面,是在action标签里面加上 result标签来控制,这种设置的页面跳转,称之为 局部结果页面但是我们有时候在很多个action里面,针对不同的结果进行跳转时,也有可能跳转同一个页面,那么这个时候就可以配置全局结果页面。
1.1局部结果
在action里面写上的result跳转的页面,称之为局部结果页面配置
<action name="demo01_*" class="demo.web.action.ActionDemo01" method="{1}">
<result name="error">/error.jsp</result>
</action>
2全局结果
如果有多个action的结果跳转的页面是一样的,那么我们可以提取出来,做成全局结果页面的配置. 全局页面通过
package标签中配置global-results标签来定义
<package name="test" extends="struts-default" namespace="/">
<global-results>
<result name="error">/error.jsp</result>
</global-results>
....
</package>
2.结果的类型(页面的跳转)
根据前面学的servlet知识,我们知道服务器响应给浏览器的时候,有三种类型:response响应JSON数据&请求转发 & 重定向。 对于Struts2而言,无非就是Action跳转到页面,Action跳转到Action....
2.1Action跳转页面
转发(默认)
<result name="success" type="dispatcher">/index.jsp</result>
- 重定向
<result name="success" type="redirect">/index.jsp</result>
2.2Action跳转Action
转发
<action name="demo01_*" class="demo.web.action.ActionDemo01" method="{1}">
<result name="success" type="chain">demo02_fun02</result>
</action>
<action name="demo02_*" class="demo.web.action.ActionDemo02" method="{1}">
</action>
- 重定向
<action name="demo01_*" class="demo.web.action.ActionDemo01" method="{1}">
<result name="success" type="redirectAction">demo02_fun02</result>
</action>
<action name="demo02_*" class="demo.web.action.ActionDemo02" method="{1}">
</action>
2.3其它的结果
一般来说,我们平常的请求到来,我们要不就是跳转到 页面上 ,要不就是跳转到下一个action 去。 但是除了这两种结果之外,我们仍然还有一些其他结果类型可以控制.
比如: 我们可以返回一个文件数据给客户端 (比如文件下载).再比如: 我们可以返回一个json字符串给来请求的页面,而不是重新打开新的页面 (有点像之前的Ajax请求,返回json数据)
2.3.1响应JSON数据
导入struts-json-plugin-xxx.jar
Java代码
public class ActionDemo01 extends ActionSupport {
private User json;
public User getJson() {
return json;
}
public String fun01(){
json = new User();
json.setName("张三");
json.setAge(18);
json.setPassword("123456");
return "success";
}
}
- 配置文件
<struts>
<package name="test" extends="json-default" namespace="/">
<action name="demo01" class="demo.web.action.ActionDemo01" method="fun01">
<result name="success" type="json">
<param name="root">json</param><!--这里的name必须是root 至于这个json 是我们在action里面的成员 变量 json -->
</result>
</action>
</package>
</struts>
注意:
root:配置对象。action类中必须提供一个和root值相同的属性名称,且需要提供getter方法。
package需要继承json-default
result的type值是json
六,Struts2中的Servlet的API的访问
客户端与服务端交互时,通常会带参数过来,服务器也会回写数据给客户端。在此过程中,参与着请求,和响应,以及会话。servlet在此过程中提供了HttpServletRequest作为获取请求数据的方案,HttpServletResponse作为响应的方案,HttpSession负责了会话方案。Struts其实是基于servlet实现的web框架,他需要遵循规则提供请求,响应和会话的API供开发人员使用,因此Struts针对这一问题提供了自己的一套API封装,提供了多种方式的访问。
1.ActionContext
1.1概述
ActionContext是Action的上下文,Struts2自动在其中保存了一些在Action执行过程中所需的对象,比如session, parameters等。Struts2会根据每个执行HTTP请求的线程来创建对应的ActionContext,即一个线程有一个唯一的ActionContext。
1.2使用
获得(创建)ActionContext
ActionContext context = ActionContext.getContext();
获得请求参数
Map<String, Object> parameters = context.getParamters();
相当于Servlet中的request.getParamters()方法,只能获得所有的请求参数
2.ServletActionContext
2.1概述
ServletActionContext继承子ActionContext,因此比ActionContext功能要强大。ServletActionContext提供了多个静态方法。
2.2使用
获得Request对象
HttpServletRequest request = ServletActionContext.getRequest();
获得Response对象
HttpServletResponse response = ServletActionContext.getResponse();
获得ServletContext
ServletContext servletContext = ServletActionContext.getServletContext();
3.实现接口的方式
编写Action,让Action使用实现特定的接口的方式访问Servlet的API,有如下接口可以实现
ServletContextAware
ServletRequestAware
ServletResponseAware
SessionAware
ApplicationAware
Eg:
public class ActionDemo03 extends ActionSupport implements ServletRequestAware { private HttpServletRequest request; public String fun03() throws IOException{ HttpServletRequest request = ServletActionContext.getRequest(); String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println(username+":"+password); return NONE; } @Override public void setServletRequest(HttpServletRequest request) { this.request = request; } }
七,获得请求参数
1.获得零散数据
1.1使用上面介绍的Struts2中的Servlet的API获取
ActionContext
//1.创建ActionContext对象 ActionContext context = ActionContext.getContext(); //2.获得所有的请求参数 Map<String, Object> parameters = context.getParamters();
ServletActionContext
//1.获得request对象 HttpServletRequest request = ServletActionContext.getRequest(); requet.getParameter(String key); requet.getParameterValues(String key); requet.getParameterMap();
1.2静态参数
页面
<h1>01使用静态属性</h1>
<form method="post" action="${pageContext.request.contextPath }/demo01">
用户名:<input type="text" name="username"/><br/>
密 码:<input type="password" name="password"/><br/>
<input type="submit"/>
</form>
Action.java
public class ActionDemo01 extends ActionSupport {
private String username;//和表单里面的name属性值要一致,并且提供set方法
private String password;//和表单里面的name属性值要一致,并且提供set方法
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public String fun01(){
System.out.println(username+":"+password);
return NONE;
}
}
2.获得封装后的数据(对象)
2.1属性驱动
页面
<h1>01使用属性驱动方式</h1>
<form method="post" action="${pageContext.request.contextPath }/demo01">
用户名:<input type="text" name="user.username"/><br/>
密 码:<input type="password" name="user.password"/><br/>
<input type="submit"/>
</form>
Action.java
public class ActionDemo01 extends ActionSupport {
//1. User类里面的字段属性需要和表单里面的name属性一致, 且提供无参构造
//2. user需要set和get方法
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String fun01(){
System.out.println(user.toString());
return NONE;
}
}
2.2模型驱动【重点】
页面
<h1>02使用模型驱动方式</h1>
<form method="post" action="${pageContext.request.contextPath }/demo02">
用户名:<input type="text" name="username"/><br/>
密 码:<input type="password" name="password"/><br/>
<input type="submit"/>
</form>
Action.java
public class ActionDemo02 extends ActionSupport implements ModelDriven<User> {
private User user;
public String fun02(){
System.out.println(user.toString());
return NONE;
}
@Override
public User getModel() {
if(user == null){
user = new User();
}
return user;
}
}
2.3封装到集合
封装到集合,一般我们会在批量添加 、批量更新场景下见到。也就是说页面上同一个请求,这时候提交过来多份数据,如果我们是批量添加用户的话,可能会提交过来多个用户,那么这个时候,我们就需要把他们封装到List集合或者Map集合中去。 刨去批量操作、我们比较少用这种封装到集合的知识点。
2.3.1封装到list
页面
<h1>01封装到list</h1>
<form method="post" action="${pageContext.request.contextPath }/demo01">
用户名:<input type="text" name="list[0].username"/><br/>
密 码:<input type="password" name="list[0].password"/><br/>
用户名:<input type="text" name="list[1].username"/><br/>
密 码:<input type="password" name="list[1].password"/><br/>
<input type="submit"/>
</form>
Action.java
public class ActionDemo01 extends ActionSupport {
private List<User> list;
public List<User> getList() {
return list;
}
public void setList(List<User> list) {
this.list = list;
}
public String fun01(){
System.out.println(list.toString());
return NONE;
}
}
2.3.2封装到Map
页面
<h1>02封装到map</h1>
<form method="post" action="${pageContext.request.contextPath }/demo02">
用户名:<input type="text" name="map['user1'].username"/><br/>
密 码:<input type="password" name="map['user1'].password"/><br/>
用户名:<input type="text" name="map['user2'].username"/><br/>
密 码:<input type="password" name="map['user2'].password"/><br/>
<input type="submit"/>
</form>
Action.java
public class ActionDemo02 extends ActionSupport {
private Map<String, User> map;
public Map<String, User> getMap() {
return map;
}
public void setMap(Map<String, User> map) {
this.map = map;
}
public String fun02(){
Set<Entry<String, User>> entrySet = map.entrySet();
for (Entry<String, User> entry : entrySet) {
System.out.println(entry.getKey()+":"+entry.getValue().toString());
}
return NONE;
}
ssh框架-Struts2(一)的更多相关文章
- Eclipse搭建SSH框架(Struts2+Spring+Hibernate)
见识少的我经过一天多的研究才知道,在MyEclipse中搭好的框架的配置文件和jar包是通用的.接下来——亮剑! 工具:Eclipse+Tomcat+Mysql 一.先在Eclipse中配置好Tomc ...
- ssh框架-Struts2(二)
上篇文章我们了解了怎么配置struts.xml文件,以及前端控制器配置怎么配置,,Action进阶,Result结果配置,Struts2中的Servlet的API的访问,以及怎么获得请求参数.今天我们 ...
- [ SSH框架 ] Struts2框架学习之一
一.Struts2框架的概述 Struts2是一种基于MVC模式的轻量级Web框架,它自问世以来,就受到了广大Web开发者的关注,并广泛应用于各种企业系统的开发中.目前掌握 Struts2框架几乎成为 ...
- [ SSH框架 ] Struts2框架学习之二
一.Struts2访问Servlet的API 前面已经对 Struts2的流程已经执行完成了,但是如果表单中有参数如何进行接收又或者我们需要向页面保存一些数据,又要如何完成呢?我们可以通过学习 Str ...
- [ SSH框架 ] Struts2框架学习之四(自定义拦截器)
一.Struts2的拦截器 1.1 拦截器概述 拦截器,在AOP( Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作.拦截 ...
- [ SSH框架 ] Struts2框架学习之三(OGNl和ValueStack值栈学习)
一.OGNL概述 1.1 什么是OGNL OGNL的全称是对象图导航语言( object-graph Navigation Language),它是一种功能强大的开源表达式语言,使用这种表达式语言,可 ...
- SSH框架-Struts2基础-Action
Struts2的目录结构: 解压apps目录下的struts2-blank.war: 仿照这个最基本的项目,拷贝相关文件: 1.拷贝apps/struts2-blank/WEB-INF/classes ...
- 用MyEclipse搭建SSH框架(Struts2 Spring Hibernate)
1.new一个web project. 2.右键项目,为项目添加Struts支持. 点击Finish.src目录下多了struts.xml配置文件. 3.使用MyEclipse DataBase Ex ...
- SSH框架(三) struts2的登陆示例
因为最近在学习使用SSH框架(struts2+spring+hibernate),下面来介绍表现层struts2的使用方法. (一)添加struts2的包 见上一篇博客,先看一下添加的各个文件的目录结 ...
随机推荐
- org.hibernate.MappingException:Unknown entity:java.util.ArrayList
1.错误描述 [CQ] ERROR [http-apr-8888-exec-3] com.opensymphony.xwork2.util.logging.commons.CommonsLogger. ...
- 芝麻HTTP:在无GUI的CentOS上使用Selenium+Chrome
各位小伙伴儿的采集日常是不是被JavaScript的各种点击事件折腾的欲仙欲死啊?好不容易找到个Selenium+Chrome可以解决问题! 但是另一个▄█▀█●的事实摆在面前,服务器都特么没有GUI ...
- 异常-----freemarker.template.TemplateException
一,案例一 1.1.错误描述 五月 30, 2014 11:33:57 下午 freemarker.log.JDK14LoggerFactory$JDK14Logger error 严重: Templ ...
- 第二个scala程序
计算昨日收益,读取hdfs文件,使用临时表sqlcontext进行计算,结果保存于mysql中. 之前考虑过将结果存储于Hbase中,由于各种原因及问题,在加上数据量真的很小很小,就改成mysql了. ...
- SpringBoot集成Shiro并用MongoDB做Session存储
之前项目鉴权一直使用的Shiro,那是在Spring MVC里面使用的比较多,而且都是用XML来配置,用Shiro来做权限控制相对比较简单而且成熟,而且我一直都把Shiro的session放在mong ...
- luogu【P2753】[USACO4.3]字母游戏Letter Game
这个题...一开始看了很久题目(并且问了机房几个大佬)才明白题意.. (原题入口) 题意 大概是一开始给你一些字母出现的次数 你之后组成的单词(最多两个单词)每个字母出现次数 必须小于或等于标准(st ...
- 清橙A1202&Bzoj2201:彩色圆环
因为Bzoj是权限题,所以可以去清橙做一下 Sol 突然考了一道这样的题,考场上强行\(yy\)出来了 win下评测Long double爆零TAT 首先肯定是破环为链变成序列问题辣 那么就要求第一个 ...
- ubuntu中eclipse 不支持gbk编码问题解决办法
今天在ubuntu 下, 把Windows下工程导入Linux下Eclipse中,由于工程代码,是GBK编码,而Ubuntu默认不支持GBK编码,所以,要让Ubuntu支持GBK. 方法如下: 1.修 ...
- this->的作用
参考:https://www.zhihu.com/question/23324143 1.来源: 当年没有C++编译器,只能通过C++转成C语言才编译.而C++中的class就被翻译C语言的struc ...
- iOS 神秘而又强大的传感器系统 (附demo)
iOS中的各种传感器: 随着科技的发展,机器感知人的行为!Goole的无人驾驶汽车到李彦宏的无人驾汽车,都带入了各种计算及传感. 为了研究自然现象和制造劳动工具,人类必须了解外界的各类信息.了解外界信 ...