Struts2框架基本学习(二)
一、Struts2的Servlet的API的访问
在使用Struts2的框架的过程中,发现Struts2和Servlet的API是解耦合的。在实际开发中,经常使用到Servlet的API,比如进行登录,将用户的信息保存到Session中,有的时候需要向页面输出一些内容,用到response对象。涉及到Servlet的API的访问。
1、struts2的Servlet的API的访问
(1) 完全解耦合的方式
- 编写jsp
<h1>Struts2访问Servlet的API</h1>
<h3>方式一:完全解耦合的方式</h3>
<form action="${ pageContext.request.contextPath }/requestDemo1.action" method="post">姓名:<input type="text" name="name"/><br/>密码:<input type="password" name="password"/><br/><input type="submit" value="提交">
</form>
- 编写Action
public class RequestDemo1 extends ActionSupport {@Overridepublic String execute() throws Exception {// 1、接收参数:// 利用Struts2中的对象ActionContext对象ActionContext context = ActionContext.getContext();// 调用ActionContext中的方法// 类似于Map<String,String[]> request.getParameterMap;Map<String, Object> map = context.getParameters();for (String key : map.keySet()) {String[] values = (String[]) map.get(key);System.out.println(key + " " + Arrays.toString(values));}// 2、向域对象中存入对象context.put("reqName", "reqValue"); //相当于request.setAttribute();context.getSession().put("sessName", "sessValue"); //相当于session.setAttrubute();context.getApplication().put("appName", "appValue"); //相当于application.setAttribute();return SUCCESS;}
}
注意:这种方式只能获得代表request、session、application的数据的Map集合,不能操作这些对象的本身的方法。
(2) 使用Servlet的API的原生方式
- 编写JSP
<h3>方式二:使用原生的方式访问</h3>
<form action="${ pageContext.request.contextPath }/requestDemo2.action" method="post">姓名:<input type="text" name="name"/><br/>密码:<input type="password" name="password"/><br/><input type="submit" value="提交">
</form>
- 编写Action
public class RequestDemo2 extends ActionSupport {@Overridepublic String execute() throws Exception {// 1、接收数据// 直接获得request对象,通过ServletActionContextHttpServletRequest request = ServletActionContext.getRequest();Map<String, String[]> map = request.getParameterMap();for (String key : map.keySet()) {String[] values = map.get(key);System.out.println(key + " " + Arrays.toString(values));}// 2、向域对象中存入数据// 向request中保存数据request.setAttribute("reqName", "reqValue");// 向session中保存数据request.getSession().setAttribute("sessName", "sessValue");// 向application中存入数据ServletActionContext.getServletContext().setAttribute("appName", "appValue");return SUCCESS;}
}
注意:这种方式可以操作域对象的数据,同时也可以获得对象的方法。
(3) 接口注入的方式(很少用)
- 编写JSP
<h3>方式三:接口注入的方式</h3>
<form action="${ pageContext.request.contextPath }/requestDemo3.action" method="post">姓名:<input type="text" name="name"/><br/>密码:<input type="password" name="password"/><br/><input type="submit" value="提交">
</form>
- 编写Action
public class RequestDemo3 extends ActionSupport implements ServletRequestAware,ServletContextAware {private HttpServletRequest request;private ServletContext context;@Overridepublic String execute() throws Exception {// 1、接收参数// 通过接口注入方式获得request对象Map<String, String[]> map = request.getParameterMap();for (String key : map.keySet()) {String[] values = map.get(key);System.out.println(key + " " + Arrays.toString(values));}// 2、向域对象中保存数据// 向request中保存数据request.setAttribute("reqName", "reqValue");// 向session中保存数据request.getSession().setAttribute("sessName", "sessValue");// 向application中保存数据context.setAttribute("appName", "appValue");return super.execute();}@Overridepublic void setServletRequest(HttpServletRequest request) {this.request = request;}@Overridepublic void setServletContext(ServletContext context) {this.context = context; }
}
Servlet是单例的,多个程序访问同一个Servlet只会创建一个Servlet的实例。Action是多例的,一次请求,创建一个Action的实例(不会出现线程安全的问题)。
二、Struts2的结果页面的配置
1、 结果页面配置
(1) 全局结果页面
全局结果页面:全局结果页面指的是,在包中配置一次,其他的在这个包中的所有的action只要返回了这个值,都可以跳转到这个页面。
- 针对这个包下的所有的action的配置都有效。
在action标签下配置result:
<package name="demo1" extends="struts-default" namespace="/"><!-- 全局结果页面配置 --><global-results><result name="success">/demo1/demo2.jsp</result></global-results><action name="requestDemo1" class="cn.itcast.struts2.demo1.RequestDemo1"></action><action name="requestDemo2" class="cn.itcast.struts2.demo1.RequestDemo2"></action><action name="requestDemo3" class="cn.itcast.struts2.demo1.RequestDemo3"></action></package>
(2) 局部结果页面
局部结果页面:局部结果页面指的是,只能在当前的action中的配置有效。
- 针对当前的action有效。
在package标签下配置global-results:
<package name="demo1" extends="struts-default" namespace="/"><!-- 全局结果页面配置 --><global-results><result name="success">/demo1/demo2.jsp</result></global-results><action name="requestDemo1" class="cn.itcast.struts2.demo1.RequestDemo1"><result name="success">/demo1/demo2.jsp</result></action><action name="requestDemo2" class="cn.itcast.struts2.demo1.RequestDemo2"></action><action name="requestDemo3" class="cn.itcast.struts2.demo1.RequestDemo3"></action></package>
2、result标签的配置
result标签用于配置页面的跳转。在result标签上有两个属性:
- name属性 :逻辑视图的名称。默认值:success
- type属性 :页面跳转的类型。
- dispatcher:默认值,请求转发。(Action转发JSP)
- redirect:重定向。(Action重定向JSP)
- chain:转发。(Action转发Action)
- redirectAction:重定向。(Action重定向Action)
- stream:Struts2中提供文件下载的功能。
三、Struts2的数据的封装
Struts2框架是一个web层框架,web层框架(框架:软件的办成品,完成一部分功能)。Struts2提供了数据封装的功能。
1、Struts2的数据封装
(1) 属性驱动:提供属性set方法的方式(不常用)
- 编写页面
<h3>方式一:属性驱动-提供set方法的方式</h3>
<form action="${ pageContext.request.contextPath }/userAction1.action" method="post">用户名:<input type="text" name="username"/><br/>密码:<input type="password" name="password"/><br/>年龄:<input type="text" name="age"/><br/>生日:<input type="text" name="brithday"/><br/>工资:<input type="text" name="salary"/><br/><input type="submit" value="提交">
</form>
- 编写Action
public class UserAction1 extends ActionSupport {// 提供对应的属性private String username;private String password;private Integer age;private Date brithday;private Double salary;// 提供属性对应的set方法public void setUsername(String username) {this.username = username;}public void setPassword(String password) {this.password = password;}public void setAge(Integer age) {this.age = age;}public void setBrithday(Date brithday) {this.brithday = brithday;}public void setSalary(Double salary) {this.salary = salary;}@Overridepublic String execute() throws Exception {// 接收数据:System.out.println(username);System.out.println(password);System.out.println(age);System.out.println(brithday);System.out.println(salary);// 封装数据:User user = new User();user.setUsername(username);user.setPassword(password);user.setAge(age);user.setBrithday(brithday);user.setSalary(salary);return NONE;}
}
(2) 属性驱动:页面中提供表达式方式
- 编写JSP
<h3>方式二:属性驱动-在页面中提供表达式的方式</h3>
<form action="${ pageContext.request.contextPath }/userAction2.action" method="post">用户名:<input type="text" name="user.username"/><br/>密码:<input type="password" name="user.password"/><br/>年龄:<input type="text" name="user.age"/><br/>生日:<input type="text" name="user.brithday"/><br/>工资:<input type="text" name="user.salary"/><br/><input type="submit" value="提交">
</form>
- 编写Action
public class UserAction2 extends ActionSupport {// 提供私有的User对象private User user;// 提供user的set和get方法:一定得提供get方法public User getUser() {return user;}public void setUser(User user) {this.user = user;}@Overridepublic String execute() throws Exception {System.out.println(user);return NONE;}
}
注意一定要有get方法
(3) 模型驱动:采用模型驱动方式(最常用)
- 编写JSP
<h3>方式三:模型驱动-采用模型驱动方式</h3>
<form action="${ pageContext.request.contextPath }/userAction3.action" method="post">用户名:<input type="text" name="username"/><br/>密码:<input type="password" name="password"/><br/>年龄:<input type="text" name="age"/><br/>生日:<input type="text" name="brithday"/><br/>工资:<input type="text" name="salary"/><br/><input type="submit" value="提交">
</form>
- 编写Action
public class UserAction3 extends ActionSupport implements ModelDriven<User>{// 模型驱动使用的对象:前提必须手动提供对象的实例。private User user = new User();// 手动实例化User@Override// 模型驱动需要使用的方法:public User getModel() {return user;}@Overridepublic String execute() throws Exception {System.out.println(user);return NONE;}
}
- 模型驱动方式最常用的方式:
- 缺点:只能同时向一个对象中封装数据。
- 使用第二种可以向多个对象中同时封装数据:
2、关于INPUT逻辑视图
(1) INPUT的逻辑视图的配置
- Action接口中提供了五个逻辑视图的名称:
- SUCCESS
- ERROR
- LOGIN
- INPUT :input在某些拦截器中会使用。
- NONE
四、Struts2的复杂类型的数据封装
在实际开发中,有可能遇到批量向数据库中插入记录,需要在页面中将数据封装到集合中。
1、封装数据到List集合中
- 编写JSP
<h3>封装到List集合中:批量插入商品</h3>
<form action="${ pageContext.request.contextPath }/productAction1.action" method="post">商品名称:<input type="text" name="products[0].name"><br/>商品价格:<input type="text" name="products[0].price"><br/>商品名称:<input type="text" name="products[1].name"><br/>商品价格:<input type="text" name="products[1].price"><br/>商品名称:<input type="text" name="products[2].name"><br/>商品价格:<input type="text" name="products[2].price"><br/><input type="submit" name="提交">
</form>
- 编写Action
public class ProductAction1 extends ActionSupport {private List<Product> products;// 提供集合的set方法public void setProducts(List<Product> products) {this.products = products;}public List<Product> getProducts() {return products;}@Overridepublic String execute() throws Exception {for (Product product : products) {System.out.println(products);}return NONE;}
}
注意:必须有set和get方法。
2、封装数据到Map集合中
- 编写JSP
<h3>封装到Map集合中:批量插入商品</h3>
<form action="${ pageContext.request.contextPath }/productAction2.action" method="post">商品名称:<input type="text" name="map['one'].name"><br/>商品价格:<input type="text" name="map['one'].price"><br/>商品名称:<input type="text" name="map['two'].name"><br/>商品价格:<input type="text" name="map['two'].price"><br/>商品名称:<input type="text" name="map['three'].name"><br/>商品价格:<input type="text" name="map['three'].price"><br/><input type="submit" name="提交">
</form>
- 编写Action
public class ProductAction2 extends ActionSupport {private Map<String, Product> map;public Map<String, Product> getMap() {return map;}public void setMap(Map<String, Product> map) {this.map = map;}@Overridepublic String execute() throws Exception {for (String key : map.keySet()) {Product product = map.get(key);System.out.println(key + " " + product);}return NONE;}
}
五、综合练习CRM:保存客户
1、环境搭建
修改html为jsp。
2、代码实现
(1) 保存操作的流程
- 点击左侧的菜单页面:
- 跳转到添加页面(经过Action):
- 在添加页面中输入指定的信息,点击【保存】
- 将数据提交到Action–>Service–>DAO
- 最终回到列表页面
(2) 第一步:修改菜单页面上链接:
<TR><TD class=menuSmall><A class=style2 href="${ pageContext.request.contextPath }/customer_saveUI.action" target=main>- 新增客户</A></TD>
</TR>
(3) 第二步:编写Action中的saveUI的方法
// 跳转到添加页面的方法public String saveUI() {return "saveUI";}
(4) 第三步:配置页面的跳转
<package name="crm" extends="struts-default" namespace="/"><action name="customer_*" class="cn.itcast.web.action.CustomerAction" method="{1}"><result name="findSuccess">/jsp/customer/list.jsp</result><result name="saveUI">/jsp/customer/add.jsp</result></action></package>
(5) 第四步:修改添加页面
<FORM id=form1 name=form1action="${pageContext.request.contextPath }/customer_save.action"method=post>
(6) 第五步:完成保存操作
- 编写Action
- 编写Service
@Override// 业务成保存客户的方法public void save(Customer customer) {// 调用DAOCustomerDao customerDao = new CustomerDaoImpl();customerDao.save(customer);}
- 编写DAO
@Override// 保存客户的方法public void save(Customer customer) {Session session = HibernateUtils.getCurrentSession();Transaction transaction = session.beginTransaction();session.save(customer);transaction.commit();}
(7) 第六步:配置页面的跳转
Struts2框架基本学习(二)相关推荐
- (转)MyBatis框架的学习(二)——MyBatis架构与入门
http://blog.csdn.net/yerenyuan_pku/article/details/71699515 MyBatis框架的架构 MyBatis框架的架构如下图: 下面作简要概述: ...
- Struts2框架的学习遇到的问题
第一个问题: java.lang.NullPointerException at com.txkj.action.shopInfo.ShopinfoAction.updateInfo(Shopinfo ...
- java struts2 框架 入门简介
目录 一.Struts2框架执行流程 二.Struts2的快速入门 1.导入jar包 2.配置web.xml文件 3.配置struts.xml文件 4.创建Action来完成逻辑操作 三.Struts ...
- struts2框架的总结
struts2框架的学习心得 经过一段时间的学习,逐渐学会了java的一些框架,想在这里做个总结,可能有一些不足之处,日后补充. 一.struts2框架的历史 struts2框架是由ap ...
- struts2找不到action_第一次用上Struts2框架做Web开发的体验……
SliiyStruts2 又名 sb-struts2,因为struts真的太难用了(也许在很多年前是很好用的,但是现在看来,被其他框架秒成渣) 前言 想不到我还是得和这struts框架打交道啊,从一开 ...
- (转)MyBatis框架的学习(三)——Dao层开发方法
http://blog.csdn.net/yerenyuan_pku/article/details/71700957 使用MyBatis开发Dao层,通常有两个方法,即原始Dao开发方法和Mappe ...
- Struts2框架学习(二) Action
Struts2框架学习(二) Action Struts2框架中的Action类是一个单独的javabean对象.不像Struts1中还要去继承HttpServlet,耦合度减小了. 1,流程 拦截器 ...
- Struts2框架学习笔记_Struts2入门
文章为学习struts的笔记,可供读者参考,有不足之处还望之指出. 参考: POJO与JavaBean的区别 Velocity Velocity官网 FreeMarker XSLT struts2 学 ...
- Struts2框架学习总结(从入门到精通)
文章目录 一.Struts2入门 struts2概述 struts2入门案例 struts2底层执行过程 struts2相关配置 struts2的核心配置文件struts.xml struts2常量配 ...
最新文章
- HarmonyOS UI开发 StackLayout(堆栈布局) 的使用
- 怎么让代码不再臃肿,写的像诗一样优雅
- php session 跨子域和跨服务器解决方式
- NSDateFormatter设定日期格式
- 即时通讯成为热门传播媒体
- 在台湾当程序员是一种什么样的体验?
- python方法的分类(实例方法、类方法、静态方法)
- How to add jdk8 in Eclipse Indigo
- Python Imaging Library: ImageQt Module(图像QT模块)
- JAVA 内部类(innerclasses)
- 各种VC9 VC11版本的Apache
- c++程序添加资源文件及释放文件
- 电脑如何与移动硬盘实现自动同步备份?
- 简历中的“项目经验”该怎么写?
- SwiftUI4 iOS16 新特性之 WeatherKit免费天气API使用教程(WWDC 2022教程含源码)
- 记jmeter测试千人在线并且保持10分钟登陆Case
- win10 uwp 使用 Border 布局
- 【moeCTF题解-0x04】Crypto
- java反编译工具真的很强大!
- 系统级程序设计第一课