简介
Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。
Struts2=struts1+webwork、
框架流程
简单登录案例
登录页面
<body>
<form action="${pageContext.request.contextPath}/login" mehtod="post">
username:<input type="text" name="username" />
password:<input type="password" name="password" />
<input type="submit" value="提交" />
</form>
</body>
servlet
public class loginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
if("tom".equals(username)&&"123".equals(password)){
response.sendRedirect(request.getContextPath()+"/success.jsp");
}else{
response.sendRedirect(request.getContextPath()+"/msg.jsp");
}
}
struts2配置文件加载顺序
第一个加载的是default.properties文件
位置:strtus2-core.jar包 org.apache.struts2包下
作用:主要是声明了struts2框架的常量
第二个加载的是一批配置文件
Strtus-default.xml
位置:struts2-corl.jar
作用:声明了interceptor result bean
Strtus-plugin.xml
位置:在strtus2的插件包中
作用:主要用于插件的配置声明
Strtus.xml
位置:在我们自己的工程中
作用:用于我们自己工程使用strtus2框架的配置
第三个加载的是自定义的strtus.properties
位置:都是在自己工程的src下
作用:定制常量
第四自定义配置提供
第五加载的是web.xml配置文件
主要是加载strtus2框架在web.xml文件中的相关配置.
第六 bean相关配置
Struts.xml配置文件介绍
package配置
- name属性 作用:定义一个包的名称,它必须唯一。
- namespace属性 作用:主要是与action标签的name属性联合使用来确定一个action 的访问路径
- extends属性 作用:指定继承自哪个包。一般值是strtus-default包是在strtus-default.xml文件中声明的。
- abstruct属性 它代表当前包是一个抽象的,主要是用于被继承
action配置
- name属性 作用:主要是与package的namespace联合使用来确定一个action的访问路径
- class属性 作用:用于指示当前的action类
- method属性 作用:用于指示当前的action类中的哪个方法执行
result配置
它主要是用于指示结果视图
- name属性 作用是与action类的method方法的返回值进行匹配,来确定跳转路径
- type属性 作用是用于指定跳转方式
<struts>
<constant name="struts.devMode" value="true"></constant>
<package name="default" namespace="/" extends="struts-default">
<action name="login" class="com.itheima.web.loginAction" method="login">
<result name="success">success.jsp</result>
<result name="msg">msg.jsp</result>
</action>
<action name="test">
<result>/success.jsp</result>
</action>
</package>
</struts>
struts框架封装数据
主要有两种方式:
属性驱动
- 直接在action类中提供与请求参数匹配属性,提供get/set方法
- 在action类中创始一个javaBean,对其提供get/set ,在请求时页面上要进行修改,例如 user.username user.password ,要使用ognl表达式
以上两种方式的优缺点:
第一种比较简单,在实际操作我们需要将action的属性在赋值给模型(javaBean) 去操作
第二种:不需要在直接将值给javaBean过程,因为直接将数据封装到了javaBean中。它要求在页面上必须使用ognl表达式,就存在页面不通用问题。
模型驱动
步骤:
- 让Action类要实现一个指定接口ModelDriven
- 实例化模型对象(就是要new出来javaBean)
- 重写getModel方法将实例化的模型返回。
ognl表达式
OGNL是Object-Graph Navigation Language(对象图导航语言)的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
//支持对象操作
@Test
public void test() throws OgnlException{
OgnlContext context=new OgnlContext();//它就是一个map
//操作
Object root = context.getRoot();
Object value = Ognl.getValue("'hello'.length()",context,context.getRoot());
System.out.println(value);
}
//支持静态成员的访问
@Test
public void test2() throws OgnlException{
OgnlContext context=new OgnlContext();
//操作
Object value = Ognl.getValue("@java.lang.Math@random()", context, context.getRoot());
Object value2 = Ognl.getValue("@java.lang.Math@PI",context,context.getRoot());
System.out.println(value);
System.out.println(value2);
}
//访问上下文
@Test
public void test3() throws OgnlException{
OgnlContext context=new OgnlContext();
//操作
//像上下文中存储数据
context.put("username","zhangsan");
Object value = Ognl.getValue("#username",context,context.getRoot());
System.out.println(value);
}
@Test
public void test4() throws OgnlException{
OgnlContext context=new OgnlContext();
Map<String,String> map=new HashMap<String,String>();
map.put("name", "fox");
context.put("name", "1234");
context.setRoot(map);
//操作
Object value = Ognl.getValue("#name",context,context.getRoot());
System.out.println(value);
//如果从根中获取数据,不需要添加#号,如果不是从根中获取,需要#
}
使用
<%@ taglib uri="/struts-tags" prefix="s" %>
<body>
<s:property value="'hello'.length()"/>
<s:property value="@java.lang.Math@PI"/>
</html>
valueStack 值栈
我们使用valueStack的主要目的是为我将我们action中产生的数据携带到页面上,也就是说valueStack它就是一个容器。
当客户端向我们发送一个请求,服务器就会创始一个Action来处理请求,struts2中的action是一个多例,每一次请求都会有一个新的action对应。所以它不存在线程安全问题。
一个valueStack对应一个action,valueStack贯穿整个action的生命周期。
rquest-------àAction------àValueStack struts2框架将valueStack保存在request中。
valueStack主要有两部分组成:
CompoundRoot:它就是一个ArrayList
它主要存储的是action的相关数据
Map<String,Object> context:就是一个Map
Context中主要存储了一些引用,这个引用主要是关于web开发中相关信息
pameters :请求参数
request:请求对象中所有属性
session:会话对象中所有属性
application:application对象中的所有发展
以上都是Map
在struts2框架中我们通过ognl表达式来获取valueStack中数据,没有使用#就会从CompoundRoot中获取数据,
如果使用#来获取,这时就会从context中来获取.
Interceptor拦截器
Struts2中的interceptor它是基于spring aop思想,而aop思想它本质上是通过动态代理来实现。我们strtus2的拦截器它主要是拦截Action的操作,在action的执行前或执行后进行一些其它的功能操作。
自定义拦截器
<interceptors>
<interceptor name="MyIntercepter" class="com.itheima.utils.MyIntercepter"
</interceptor>
<interceptor-stack name="myStack">
<interceptor-ref name="MyIntercepter"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
![](https://i-blog.csdnimg.cn/blog_migrate/895e4bd0a976687b33829e23eb1226ed.png)
struts2文件上传
浏览器端注意事项:
表单提交方式method='post'
表单中必须有一个<input type=”file”>组件
表单中必须设置enctype=”multipart/form-data”
Struts2注解开发
@Namespace来代替<package namespace=””>
@ParentPackage来代替<package extends=””>
@Action来描述关于<action>配置
value属性<action name=””>
使用@Action的results来描述关于结果类型的配置<result>
<result name=”” type=””>
@Action(results={@Result(name=””,type=””,location=””)})
@Actions 作用:可以通过多个映射来访问同一个action
@InterceptorRef 它是用于处理拦截器的
@Namespace("/")
@ParentPackage("struts-default")
public class Login extends ActionSupport implements ModelDriven<User>{
private User user =new User();
public User getModel() {
// TODO Auto-generated method stub
return user;
}
@Action(value="login",results={@Result(name="success",location="/success.jsp"),@Result(name="login",location="/login.jsp")})
public String login(){
if("tom".equals(user.getUsername())&&"123".equals(user.getPassword())){
ServletActionContext.getRequest().getSession().setAttribute("user", user);
return "success";
}else{
this.addActionError("用户名错误....");
return "login";
}
}