Java网课基础笔记(31)19-08-13
Action使用Servlet相关API目录Action使用Servlet相关API解耦方式调用API(间接调用 了解)耦合方式直接调用API接口注入方式操作Servlet API(了解)方式一 实现接口,访问Action时完成注入通过ServletActionContext类的静态方法直接获取Servlet API(推荐)方式二 使用Servle...
Action使用Servlet相关API
目录
通过ServletActionContext类的静态方法直接获取Servlet API(推荐)
需要分析:为了简化开发,struts2默认情况下讲servlet API(比如:request对象、response对象,session对象、application对象)都隐藏起来了。但是在某些情况下,外面还需要调用servlet API,比如登录的时候将用户信息保存到session域中。
struts2中提供了3种方式来获取servlet的API
- 解耦方式获取,借助ActionContext获取,方便单元测试Junit(这个是struts2官方的推荐的方式,但是不利于理解,所以不推荐)
- 接口注入方式操作servlet API(了解)
- 通过servletActionContext类的静态方法直接获取servlet API(掌握)
get请求的时候,可能会出现中文乱码问题,可通过servers的server.xml中找到如下:
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
并增加 URIEncoding="UTF-8",如下
<Connector URIEncoding="UTF-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
解耦方式调用API(间接调用 了解)
- 耦合的概念:
如使用servlet的时候,调用的doget方法和dopost(HttpServletRequest,HttpServletReponse)方法,代码中直接关联request和response对象,这就是耦合。
- 解耦的概念:
代码中不直接依赖于request对象和response对象。
Struts2设计思想就是与Servlet API解耦合,Action中不再依赖Servlet的API
- 如何调用这些API?
struts2为我们提供了一个API,可间接调用servlet API,叫做ActionContext类(Action上下文)。可以理解为该类是一个工具类。
- 该API提供大量间接操作Servlet API方法
- getContext()返回ActionContext实例对象
- get(key)相当于HttpServletRequest的getAttribute(String name)方法
- put(String Object)相当于HttpServletRequest的setAttribute方法
- getApplication()返回一个Map对象,存取ServletContext属性
- getSession()返回一个Map对象,存取HttpSession属性
- getParameters()类似调用HttpServletRequest的getParameterMap()方法
- setAttribute(Map)将该Map实例里key-value保存为ServletContext的属性名、属性值
- setSession(Map)将该Map实例里key-value保持为HttpSession的属性名、属性值
编写IndirectServletAPIAction.java
public class IndirectServletAPIAction extends ActionSupport{
public String execute() throws Exception{
//接收参数
ActionContext context=ActionContext.getContext();
Map<String,Parameter> params=context.getParameters();
Parameter name=params.get("name");
System.out.println(name);
return NONE;
}
}
编写my.jsp
<body>
<h1>
<a href="${pageContext.request.contextPath}/indirect?name=chen">调用API)</a>
</h1>
</body>
配置struts.xml文件
<action name="indirect" class="struts_01.IndirectServletAPIAction" >
</action>
测试结果
耦合方式直接调用API
接口注入方式操作Servlet API(了解)
方式一 实现接口,访问Action时完成注入
ServletContextAware
- void setServletContext(javax.servlet.ServletContext context)
ServletRequestAware
- void setServletRequest(javax.servlet.http.HttpServletRequest request)
ServletResponseAware
- void setServletResponse(javax.servlet.http.HttpServletResponse response)
ServeltRequestAware--获取到request对象
ServletResponseAware--获取到response对象
ServletContextAware--获取到ServletContext对象
编写InjectServletAPIAction.java
public class InjectServletAPIAction extends ActionSupport implements ServletRequestAware {
HttpServletRequest request;
//自动获取request对象
@Override
public void setServletRequest(HttpServletRequest arg0) {
// TODO Auto-generated method stub
request=arg0;
}
public String execute() throws Exception {
String name=request.getParameter("name");
System.out.println(name);
request.setAttribute("msg", name);
return SUCCESS;
}
}
struts.xml配置增加action
<!-- 耦合方式直接调用 通过实现接口获取request对象 -->
<action name="inject" class="struts_01.InjectServletAPIAction" >
<result name="success">/API1.jsp</result>
</action>
编写API1.jsp
<body>
${msg}
</body>
测试结果
通过ServletActionContext类的静态方法直接获取Servlet API(推荐)
方式二 使用ServletActionContext
- static PageContext getPageContext()
- static HttpServletRequest getRequest()
- static HttpServletResponse getResponse()
- static ServletContext getServletContext()
编写DirectServletAPIAction.java
public class DirectServletAPIAction extends ActionSupport {
public String execute()throws Exception {
// TODO Auto-generated constructor stub
HttpServletRequest request=ServletActionContext.getRequest();
String name=request.getParameter("name");
System.out.println(name);
return NONE;
}
}
struts.xml增加action方法
<!-- 通过ServletActionContext类的静态方法来获取servlet的API -->
<action name="direct"
class="struts_01.DirectServletAPIAction">
</action>
测试结果
请求参数的接收机制
什么是请求参数?
比如登录、注册功能的时候,客户端需要像服务器提交登录或注册信息,这些信息都是请求参数
Servlet接受参数,request.getParameter("XXX");
方式一 属性接受参数(当属性比较少的时候可以用,不用实现接口)
编写LoginAction1.java
public class LoginAction1 extends ActionSupport {
// 通过struts2框架自动接受参数
private String username;
private String pwd;
// 通过setter方法进行赋值
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "LoginAction1 [username=" + username + ", pwd=" + pwd + "]";
}
public String execute() throws Exception {
System.out.println(toString());
return NONE;
}
}
编写login1.jsp
<body>
<h1>方式一:Action作为表单模型,提供属性和属性对应的getter方法和setter方法</h1>
<form action="${pageContext.request.contextPath}/login1.action"
method="post">
username:<input type="text" name="username"><br>
password:<input type="password " name="pwd"><br> <input
type="submit" value="登录">
</form>
</body>
struts.xml增加action 方法
<action name="login1" class="struts_01.LoginAction1" >
</action>
测试结果
方式二 使用JavaBean(耦合性较强,不利于开发)
编写UserInfo.java
public class UserInfo {
private String username;
private String pwd;
public UserInfo() {
System.out.println("UserInfo构造方法");
}
public String getUsername() {
System.out.println("getUsername");
return username;
}
public void setUsername(String username) {
System.out.println("setUsername");
this.username = username;
}
public String getPwd() {
System.out.println("getPwd");
return pwd;
}
public void setPwd(String pwd) {
System.out.println("setPwd");
this.pwd = pwd;
}
}
编写LoginAction2.java
public class LoginAction2 extends ActionSupport {
private UserInfo userInfo;
public UserInfo getUserInfo() {
System.out.println("getUserInfo");
return userInfo;
}
public void setUserInfo(UserInfo userInfo) {
System.out.println("setUserInfo");
this.userInfo = userInfo;
}
public String execute()throws Exception {
System.out.println(userInfo.getUsername()+"--"+userInfo.getPwd());
return NONE;
}
}
编写login2.jsp
<body>
<h1>方式二</h1>
<form action="${pageContext.request.contextPath}/login2.action"
method="post">
username:<input type="text" name="userInfo.username"><br>
password:<input type="password " name="userInfo.pwd"><br> <input
type="submit" value="登录">
</form>
</body>
struts.xml增加action
<action name="login2" class="struts_01.LoginAction2" >
</action>
测试结果
方式三 模型驱动(弥补第二种的缺陷)
使用ModelDriven接口(模型驱动),对请求的数据进行封装
编写UserInfo.java
public class UserInfo {
private String username;
private String pwd;
public UserInfo() {
System.out.println("UserInfo构造方法");
}
public String getUsername() {
System.out.println("getUsername");
return username;
}
public void setUsername(String username) {
System.out.println("setUsername");
this.username = username;
}
public String getPwd() {
System.out.println("getPwd");
return pwd;
}
public void setPwd(String pwd) {
System.out.println("setPwd");
this.pwd = pwd;
}
}
编写LoginAction3.java
public class LoginAction3 extends ActionSupport implements ModelDriven<UserInfo> {
//必须手动初始化JavaBean对象
private UserInfo user = new UserInfo();;
//把页面中的数据接受到Javabean中
@Override
public UserInfo getModel() {
// TODO Auto-generated method stub
System.out.println(user);
return user;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
System.out.println(user.getUsername()+"--"+user.getPwd());
return NONE;
}
}
编写login3.jsp
<body>
<h1>方式三</h1>
<form action="${pageContext.request.contextPath}/login3.action"
method="post">
username:<input type="text" name="username"><br>
password:<input type="password " name="pwd"><br> <input
type="submit" value="登录">
</form>
</body>
struts.xml增加action
<action name="login3" class="struts_01.LoginAction3" >
</action>
测试结果
Struts2的复杂数据的封装
封装到List集合
编写product1.jsp
<body>
<form action="${pageContext.request.contextPath}/product1Action.action" method="post">
商品名称:<input type="text" name="list[0].name"><br>
商品价格:<input type="text" name="list[0].price"><br>
商品名称:<input type="text" name="list[1].name"><br>
商品价格:<input type="text" name="list[1].price"><br>
商品名称:<input type="text" name="list[2].name"><br>
商品价格:<input type="text" name="list[2].price"><br>
<input type="submit" value="批量导入">
</form>
</body>
编写Product.java
public class Product {
private String name;
private Double price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return "Product [name=" + name + ", price=" + price + "]";
}
}
编写ProductAction1.java
public class ProductAction1 extends ActionSupport {
private List<Product> list;
public List<Product> getList() {
return list;
}
public void setList(List<Product> list) {
this.list = list;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
for (Product product : list) {
System.out.println(product);
}
return NONE;
}
}
struts.xml增加action
<action name="product1Action" class="struts_01.ProductAction1" >
</action>
结果
封装到Map集合
编写product2.jsp
<body>
<form action="${pageContext.request.contextPath}/product2Action.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" value="批量导入">
</form>
</body>
编写Product.java
public class Product {
private String name;
private Double price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return "Product [name=" + name + ", price=" + price + "]";
}
}
编写ProductAction2.java
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;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
for (String key:map.keySet()) {
Product product=map.get(key);
System.out.println(key+" "+product);
}
return NONE;
}
}
struts.xml增加action
<action name="product2Action" class="struts_01.ProductAction2" >
</action>
测试结果
请求参数的类型转换机制(了解)
【问题】从上面的例子就可以看出在Action中使用了int类型接收age属性。页面传递过来的肯定是String类型,但是为什么不需要进行类型转换呢?
【原因】Struts2提供了功能强大的类型转换器,用于将请求数据封装到model对象。对于大部分常用类型,开发者根本无需创建自己的转换器。只有当内置的转换类型不够用的时候,可以自定义参数转换器。
内置的转换器
- boolean --Boolean
- char--Character
- int--Integer
- long--Long
- float--Float
- double--Double
- Date可以接收yyyy-MM-dd格式字符串
- 数组 可以将多个同名参数,转换到数组中
- 集合 支持将数据保存到List或者Map集合
编写注册案例(包含文本、数字、日期、数组)
编写regist.jsp
<body>
<h1>用户注册--内部类型转换器测试</h1>
<form action="${pageContext.request.contextPath}/regist.action"
method="post">
username:<input type="text" name="username"><br> age:<input
type="text" name="age"><br>
<h1>日期格式默认使用yyyy-MM-dd</h1>
birthday:<input type="text" name="birthday"><br> hobby:<input
type="checkbox" name="hobby" value="音乐">音乐 <input
type="checkbox" name="hobby" value="游戏">游戏 <input
type="checkbox" name="hobby" value="旅游">旅游<br> <input
type="submit" value="注册">
</form>
</body>
编写RegistAction.java
public class RegistAction extends ActionSupport{
private String username;
private int age;
private Date birthday;
private String[] hobby;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String[] getHobby() {
return hobby;
}
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
@Override
public String toString() {
return "RegistAction [username=" + username + ", age=" + age + ", birthday=" + birthday + ", hobby="
+ Arrays.toString(hobby) + "]";
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
System.out.println(toString());
return NONE;
}
}
struts.xml增加action
<action name="regist" class="struts_01.RegistAction" >
</action>
测试结果
注意:struts2日期格式默认使用yyyy-MM-dd,如果要使用其他格式,则必须自定义转换器。然后老师并没有说怎么写自定义类型转换器。一般情况下用默认的即可。
更多推荐
所有评论(0)