- 缓存问题:清空服务器项目(remove),选中项目-project-撤掉勾选buildauto-clean-选中项目右键buildproject-勾选自动创建- run
- ctrl+alt+t关联源文件,导包就导zip就行
-
window-showview-other-Javadoc可以看自带文档
image.png
1.结果跳转方式
-----------分四种
<!-- 转发 -->
<action name="Demo1Action" class="cn.itheima.a_result.Demo1Action" method="execute" >
<result name="success" type="dispatcher" >/hello.jsp</result>
</action>
<!-- 重定向 -->
<action name="Demo2Action" class="cn.itheima.a_result.Demo2Action" method="execute" >
<result name="success" type="redirect" >/hello.jsp</result>
</action>
<!-- 转发到Action -->
<action name="Demo3Action" class="cn.itheima.a_result.Demo3Action" method="execute" >
<result name="success" type="chain">
<!-- action的名字 -->
<param name="actionName">Demo1Action</param>
<!-- action所在的命名空间 -->
<param name="namespace">/</param>
</result>
</action>
<!-- 重定向到Action -->
<action name="Demo4Action" class="cn.itheima.a_result.Demo4Action" method="execute" >
<result name="success" type="redirectAction">
<!-- action的名字 -->
<param name="actionName">Demo1Action</param>
<!-- action所在的命名空间 -->
<param name="namespace">/</param>
</result>
</action>
2.访问api方式
-
action是每次访问都会创建,servlet是有线程安全问题,多个请求会访问一个servlet
image.png -
访问方式
- 最常用
public String execute() throws Exception {
//request域=> map (struts2并不推荐使用原生request域)
//不推荐
Map<String, Object> requestScope = (Map<String, Object>) ActionContext.getContext().get("request");
//推荐
ActionContext.getContext().put("name", "requestTom");
//session域 => map
Map<String, Object> sessionScope = ActionContext.getContext().getSession();
sessionScope.put("name", "sessionTom");
//application域=>map
Map<String, Object> applicationScope = ActionContext.getContext().getApplication();
applicationScope.put("name", "applicationTom");
return SUCCESS;
}
------ServletActionContext工具类来获取
//并不推荐
public String execute() throws Exception {
//原生request
HttpServletRequest request = ServletActionContext.getRequest();
//原生session
HttpSession session = request.getSession();
//原生response
HttpServletResponse response = ServletActionContext.getResponse();
//原生servletContext
ServletContext servletContext = ServletActionContext.getServletContext();
return SUCCESS;
}
-------------了解通过实现接口方式
//如何在action中获得原生ServletAPI
public class Demo7Action extends ActionSupport implements ServletRequestAware {
private HttpServletRequest request;
public String execute() throws Exception {
System.out.println("原生request:"+request);
return SUCCESS;
}
@Override
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
}
3.获得参数
-
strutsMVC
image.png - Action生命周期
1.每次请求到来时,都会创建一个新的Action实例
2.Action是线程安全的.可以使用成员变量接收参数
------------- 属性参数
<form action="${pageContext.request.contextPath}/Demo8Action">
用户名:<input type="text" name="name" /><br>
年龄:<input type="text" name="age" /><br>
生日:<input type="text" name="birthday" /><br>
<input type="submit" value="提交" />
</form>
//准备与参数键名称相同的属性
private String name;
//自动类型转换 只能转换8大基本数据类型以及对应包装类
private Integer age;
//支持特定类型字符串转换为Date ,例如 yyyy-MM-dd
private Date birthday;
--------------------对象参数
<form action="${pageContext.request.contextPath}/Demo9Action">
用户名:<input type="text" name="user.name" /><br>
年龄:<input type="text" name="user.age" /><br>
生日:<input type="text" name="user.birthday" /><br>
<input type="submit" value="提交" />
</form>
//准备user对象属性
private User user;
----------------------模型驱动
<form action="${pageContext.request.contextPath}/Demo8Action">
用户名:<input type="text" name="name" /><br>
年龄:<input type="text" name="age" /><br>
生日:<input type="text" name="birthday" /><br>
<input type="submit" value="提交" />
</form>
//struts2如何获得参数-方式2
public class Demo10Action extends ActionSupport implements ModelDriven<User> {
//准备user 成员变量
private User user =new User();
public String execute() throws Exception {
System.out.println(user);
return SUCCESS;
}
@Override
public User getModel() {
return user;
}
4.集合类型封装
-------------list,map属性
//list
private List<String> list;
//Map
private Map<String,String> map;
<form action="${pageContext.request.contextPath}/Demo11Action" method="post" >
list:<input type="text" name="list" /><br>
list:<input type="text" name="list[3]" /><br>
map:<input type="text" name="map['haha']" /><br>
<input type="submit" value="提交" />
</form>
5.添加客户
- 注意:struts和hibernate包在合并时.javassist-3.18.1-GA.jar包是重复的,删除版本低的.
public class CustomerAction extends ActionSupport implements ModelDriven<Customer> {
private CustomerService cs = new CustomerServiceImpl();
//添加客户
public String add() throws Exception {
//1 调用Service
cs.save(customer);
//2 重定向到列表action方法
return "toList";
}
@Override
public Customer getModel() {
return customer;
}
}
6.ognl表达式
- OGNL:对象视图导航语言. ${user.addr.name} 这种写法就叫对象视图导航.
OGNL不仅仅可以视图导航.支持比EL表达式更加丰富的功能. - struts2 的包中已经包含了.所以不需要导入额外的jar包
-
内部结构
image.png
//准备工作
public void fun1() throws Exception{
//准备ONGLContext
//准备Root
User rootUser = new User("tom",18);
//准备Context
Map<String,User> context = new HashMap<String,User>();
context.put("user1", new User("jack",18));
context.put("user2", new User("rose",22));
OgnlContext oc = new OgnlContext();
//将rootUser作为root部分
oc.setRoot(rootUser);
//将context这个Map作为Context部分
oc.setValues(context);
//书写OGNL
Ognl.getValue("", oc, oc.getRoot());
}
-------------------------取出root直接取出
//取出root中user对象的name属性
String name = (String) Ognl.getValue("name", oc, oc.getRoot());
Integer age = (Integer) Ognl.getValue("age", oc, oc.getRoot());
-------------------------取出context加#取出
//取出context中键为user1对象的name属性
String name = (String) Ognl.getValue("#user1.name", oc, oc.getRoot());
String name2 = (String) Ognl.getValue("#user2.name", oc, oc.getRoot());
Integer age = (Integer) Ognl.getValue("#user2.age", oc, oc.getRoot());
-------------------------赋值直接在取值语法上书写,有多个返回值返回最后一个,赋值可以多个一起写逗号隔开
//将root中的user对象的name属性赋值
Ognl.getValue("name='jerry'", oc, oc.getRoot());
String name = (String) Ognl.getValue("name", oc, oc.getRoot());
String name2 = (String) Ognl.getValue("#user1.name='张三',#user1.name", oc, oc.getRoot());
------------------//调用root中user对象的setName方法
Ognl.getValue("setName('lilei')", oc, oc.getRoot());
String name = (String) Ognl.getValue("getName()", oc, oc.getRoot());
String name2 = (String) Ognl.getValue("#user1.setName('lucy'),#user1.getName()", oc, oc.getRoot());
-----------------调用静态方法
String name = (String) Ognl.getValue("@cn.itheima.a_ognl.HahaUtils@echo('hello 强勇!')", oc, oc.getRoot());
//Double pi = (Double) Ognl.getValue("@java.lang.Math@PI", oc, oc.getRoot());
Double pi = (Double) Ognl.getValue("@@PI", oc, oc.getRoot());
-----------------ognl创建对象-list|map
//创建list对象
Integer size = (Integer) Ognl.getValue("{'tom','jerry','jack','rose'}.size()", oc, oc.getRoot());
String name = (String) Ognl.getValue("{'tom','jerry','jack','rose'}[0]", oc, oc.getRoot());
String name2 = (String) Ognl.getValue("{'tom','jerry','jack','rose'}.get(1)", oc, oc.getRoot());
//创建Map对象
Integer size2 = (Integer) Ognl.getValue("#{'name':'tom','age':18}.size()", oc, oc.getRoot());
String name3 = (String) Ognl.getValue("#{'name':'tom','age':18}['name']", oc, oc.getRoot());
Integer age = (Integer) Ognl.getValue("#{'name':'tom','age':18}.get('age')", oc, oc.getRoot());
7.ognl与Struts2结合
- 结合原理:原来的ognlcontext在struts2中改了一个名字为valuestack值栈。其中root默认是当前访问action,context被包装成了actioncontecxt数据中心,并且root和context是相互引用关系
-
栈原理是先进后出,栈是arraylist创建的
image.png
image.png - <s:debug></s:debug>
-
Context部分就是ActionContext数据中心
image.png -
struts2与ognl结合体现
image.png
image.png
image.png - 想要赋值就需要在action之前将user压入栈中,一张方法是实现接口(20个过滤器之一的) <interceptor-ref name="prepare"/>不建议,另外一个就是实现modeldriver接口(这个接口也在action调用之前)
- 配置文件中重定向传参${name}(ognl专用在配置文件中的)
<action name="Demo3Action" class="cn.itheima.d_config.Demo3Action" method="execute" >
<result name="success" type="redirectAction" >
<param name="actionName">Demo1Action</param>
<param name="namespace">/</param>
<!-- 如果添加的参数struts"看不懂".就会作为参数附加重定向的路径之后.
如果参数是动态的.可以使用${}包裹ognl表达式.动态取值
-->
<param name="name">${name}</param>
</result>
</action>
-
扩展:request对象的getAttribute方法
image.png - jsp和struts,ognl
-----------------------有var的会将循环后取到的对象放在context中
- #list(ognl语法)
<%@ taglib prefix="s" uri="/struts-tags" %>
<s:iterator value="#list" var="cust" >
<TR
style="FONT-WEIGHT: normal; FONT-STYLE: normal; BACKGROUND-COLOR: white; TEXT-DECORATION: none">
<TD>
<s:property value="#cust.cust_name" />
</TD>
</s:iterator>
-----------------------没有var的会将循环后取出的对象压在root中
<%-- <s:iterator value="#list" >
<TR
style="FONT-WEIGHT: normal; FONT-STYLE: normal; BACKGROUND-COLOR: white; TEXT-DECORATION: none">
<TD>
<s:property value="cust_name" />
</TD>
</s:iterator>
--------整体使用规则类似在java中的使用
网友评论