Struts2技术总结

想想快到年底了,能否来年再找一份高薪的工作呢?这些知识点还是要必备的。那么在我还能记得的时候,将这些东西写下来微笑(全是本人自己总结的很基础很基础的知识点,多偏向于面试方向,你懂的吐舌头,好与不好,自己爽就行。这次就慢慢写吧... ...)

一:什么是Struts2?

    Struts2是由Struts1和WebWork两个框架整合发展而来的,作用于视图层的优秀的MVC框架(m:模型, v:视图, c:控制器),基于Model2(jsp + servlet + javaBean)的设计模型

二:有必要知道的Struts2的一些jar包?

    struts2-core---Struts2框架的核心类库

    xwork-core---Command模式框架,struts2和WebWork都要基于xwork

    ognl---对象图导航语言

    fileupload----文件上传组件

    太多了也记不住,就记这几个主要的吧

三:Struts2的相关配置?

    1.核心控制器,在web工程下的web.xml配置文件中,配置Struts2的核心控制器,Struts2使用filter过滤器作为其核心控制器:StrutsPrepareAndExecuteFilter过滤器,主要处理已.action结尾的请求,传递到相对应得Action类中

    2.Struts2中内置的一些拦截器(功能很强大)

    3.strtus.xml是web应用默认的struts配置文件

    4.struts-default默认包

四:Struts.xml配置文件?

    struts.xml配置文件,主要指挥控制器运作(controller)
<?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>
  <constant name="struts.devMode" value="true"/>
  <package name="demo1" extends="struts-default">
    <action name="hello" class="com.wanghang.struts.Action">
      <result name="success">/success.jsp<?result>
    </action>
  </package>
</struts>
    如上所示:struts.xml中主要包括:
        package标签:包括name,namespace,extends,abstract四个属性
        action标签:包括name,class,method三个属性,通过calss找到动作类,通过method找到动作方法
        result标签:包括name,type两个属性
记忆技巧:三,四三二(三个标签,从外到里分别是:四个属性,三个属性,两个属性)

五:struts-default默认包有什么作用?

    strtus-default是struts内置的,其中定义了struts2内部众多的拦截器和result结果类型,而struts2很多的功能都是通过拦截器实现的。例如封装参数,文件上传下载,数据验证等,而且当包继承了struts-default包才能使用这些拦截器

六:Struts2的请求处理流程?

    1.服务器加载web应用程序

    2.加载web.xml配置文件,完成对StrutsPrepareAndExecuteFilter过滤器的实例化

    3.完成对过滤器的初始化,运行其init()方法

    4.在初始化控制器之前,加载struts.xml配置文件

    5.用户发起请求,经过过滤器,访问资源,例(http: // localhost:8080 / 工程名 / helloworld.action)

    6.从已经加载的struts.xml中寻找<action name="helloworld" class="... ...">的动作标签

    7.从而找到相对应的class动作类,进行实例化类,调用方法

    8.返回结果视图,找到struts.xml中的结果视图标签<result name="success">

    9.再进行页面的跳转helloword.html

七:拦截器和过滤器的区别(面试很可能会问)?

    1.拦截器是基于java反射机制的,而过滤器是基于函数回调

    2.过滤器要依赖于servlet容器,而拦截器不依赖servlet容器

    3.拦截器只能拦截action动作,而过滤器几乎都可以拦截

    4.拦截器可以访问值栈里的对象,而过滤器不可以

    4.拦截器基于SpringAop(面向切面编程)的思想,功能强大

八:Action类?

    sturts2中用户自己写的action类就是一个普通的java类(POJO),但是为了编程规范,Struts2为Action接口提供了一个实现类ActionSupport,其中定义了类似于表单校验,错误信息,获取国际化信息的一些方法。

    当用户自定义动作类继承ActionSupport 时,并且自定义方法时,要注意方法的格式:

  /**
   * 用户自定义动作方法
   */
  public String add() {
      return SUCCESS;
  }
    注意:1.方法一定要public修饰

                2.方法返回值是String类型(方法返回的是结果视图,具体在后边struts.xml中进行说明)

                3.方法无参数

        4.继承ActionSupport类时,可以重写execute()方法。

九:参数注入?

    1.静态参数的封装(是指‘运行期间一般不会发生改变的数据)
        主要是由一个叫做staticParam的拦截器负责注入参数的
    2.动态参数的封装(是指:运行期间由用户输入的数据,主要是通过表单输入。那就是接下来要说的部分)

十:Action类接收请求参数?

    Struts2提供了非常强大的类型转换机制用于封装请求数据到model模型对象的封装(这里的模型类指的就是普通java对象类)
    1.Action动作类充当模型类
    提供成员变量setter接收参数, 这种方式主要是通过一个叫做params的拦截器完成的
  用户名:<input type="text" name="usernaem"/><br/>
  密码:<input type="password" name="password"/><br/>   
/**
 * 动作类充当模型对象
 * 
 * @Author Hang.W
 * @Version 2016-12-20 23:44:53
 * 
 */
public class Action1 {
	private String username;
	private String password;

	public void setUsername(String username) {
		this.username = username;
	}

	public void setPassword(String password) {
		this.password = password;
	}
}
    2.创建独立的model类,通过ognl表达式封装参数
    需要在Action类中引用模型对象,提供get(),set()方法。
  用户名:<input type="text" name="usernaem"/><br/>
  密码:<input type="password" name="password"/><br/>
/**
 * 用户模型类
 * 
 * @author Hang.W
 * @version 1.0, 2016-12-20 23:51:39
 */
public class UserModel {

	private String username;

	private String password;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

}
/**
 * 动作类与模型对象分开
 * 
 * @author Hang.W
 * @version 1.0, 2016-12-20 23:56:39
 */
public class Action2 {

	private UserModel userModel;

	public UserModel getUserModel() {
		return userModel;
	}

	public void setUserModel(UserModel userModel) {
		this.userModel = userModel;
	}

}
    3.实现ModelDriven接口,重写getModel()方法(模型类这次就不写了,写太多有点烦)
    动作类实现ModelDriven接口,必须实例化模型对象,并且重写的getModel()方法中必须返回模型对象, 这种方式的参数注入主要是通过一个叫做ModelDriven的拦截器完成的。
  用户名:<input type="text" name="usernaem"/><br/>
  密码:<input type="password" name="password"/><br/>
/**
 * 模型驱动
 * 
 * @author Hang.W
 * @version 1.0, 2016-12-21 00:02:57
 */
public class Action3 implements ModelDriven<UserModel> {
	
	private UserModel userModel = new UserModel();
	
	@Override
	public UserModel getModel() {
		return this.userModel;
	}
	
}

十一:如何访问ServletAPI?

    有两种方式可以获取Servlet API,但是推荐接下来写的这种,主要是通过ActionContext的子类ServletActionContext获取Servlet的API。因此比较简单
/**
 * 如何获取ServletAPI
 * 
 * @author Hang.W
 * @version 1.0, 2016-12-21 23:40:06
 */
public class Action extends ActionSupport {
	
	@Override
	public String execute() {
		// 获取Servlet的API
		HttpServletRequest request  = servletActionContext.getRequest();
		HttpSession session = request.getSession();
		ServletContext context = servletActionContext.getServletContext();
	}
	
}
    另一种相对比较麻烦,但获取原理:是实现ServletRequestAware等接口,是 通过一个叫做ServletConfig的拦截器,将servletAPI注入进来的

十二:OGNL表达式

    OGNL:Object Graphic Navigation Language(对象图导航语言),是struts2的默认表达式语言
    作用:能够获取JavaBean的属性,List或数组中的元素,值栈中的value值

十三:contextMap(很重要,但面试也有可能会问吧)

    contextMap:是整个动过访问的数据中心,即每一次请求的所有数据都存放在这里
    contextMap就是一个Map结构:
    
    如图所示,就是整个ContextMap的结构

十四:如何获取值栈对象?

    关于取数据之前,我们先来看看如何存数据?
    1.当每次有动作访问时,就会从当前的线程中获取ActionContext对象
    2.再通过ActionContext获取ValueStack的对象
/**
 * 通用标签库动作类
 * 
 * @author Hang.W
 * @version 1.0,2016-12-23 00:06:46
 */
@SuppressWarnings("all")
public class DemoAction1 extends ActionSupport {

	@Override
	public String execute() throws Exception {

		// 获取valuestack对象
		ActionContext context = ActionContext.getContext();
		ValueStack valueStack = context.getValueStack();
        }
}
    通过这两个动作可以向值栈中存数据
    1. actionContext通过put()方法,可以将数据存入 ContextMap
    2. valueStack通过push()方法,可以将数据 压入栈顶
    注意:
            1.当valueStack使用set()方法存储时,如果root的栈顶是一个Map集合,那么直接使用Put()方法。如果不是一个Map,那么创建一个map后存入数据。
            2.当valueStack使用setValue("a", "b"),修改值时,那么第一个参数一定是OGNL表达式,不是普通的字符串
    如下所示:分别将对象,数组,集合存入contextMap中,由于Action类也是资源,那么也会加载到contextMap中
package com.wanghang.action;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.util.ValueStack;
import com.wanghang.domain.Student;

/**
 * 采用第二种方式动作类与模型类分开
 * 
 * @author Hang.W
 * @version 1.0,2016-12-23 00:23:47
 */
@SuppressWarnings("all")
public class DemoAction1 extends ActionSupport {

	private String[] str;

	private List<String> list;

	private Map<String, String> map;

	private List<Student> stu;

	@Override
	public String execute() throws Exception {

		// 获取valuestack对象
		ActionContext context = ActionContext.getContext();
		ValueStack valueStack = context.getValueStack();

		// 向contextMap中存放数据,第一位是OGNL表达式(如果contextMap中没有需要替换的对象,那么就可以自动创建一个)
		valueStack.setValue("#grade", "c");

		// valueStack向contextMap中存放数组或集合
		str = new String[] { "张三", "李四", "王五", "赵六", "周七" };

		list = new ArrayList<String>();
		list.add("张三三");
		list.add("李四四");
		list.add("王五五");
		list.add("赵六六");
		list.add("周七七");

		map = new HashMap<String, String>();
		map.put("zhangsan", "张三");
		map.put("lisi", "李四");
		map.put("wangwu", "王五");
		map.put("zhaoliu", "赵六");
		map.put("zhouqi", "周七");

		stu = new ArrayList<Student>();
		Calendar birthday = Calendar.getInstance();
		birthday.set(2020, 10, 10);
		stu.add(new Student("漩涡鸣人", 18, birthday.getTime(), "北京"));

		Calendar birthday2 = Calendar.getInstance();
		birthday.set(2010, 5, 5);
		stu.add(new Student("路飞", 17, birthday2.getTime(), "上海"));

		Calendar birthday3 = Calendar.getInstance();
		birthday.set(2015, 7, 7);
		stu.add(new Student("无脸男", 19, birthday3.getTime(), "广州"));
		
		return SUCCESS;
	}

	public String[] getStr() {
		return str;
	}

	public void setStr(String[] str) {
		this.str = str;
	}

	public List<String> getList() {
		return list;
	}

	public void setList(List<String> list) {
		this.list = list;
	}

	public Map<String, String> getMap() {
		return map;
	}

	public void setMap(Map<String, String> map) {
		this.map = map;
	}

	public List<Student> getStu() {
		return stu;
	}

	public void setStu(List<Student> stu) {
		this.stu = stu;
	}

}
    页面上取值要使用OGNL表达式来取值!
    分别:如果在contextMap中的Map中那么一定要使用#
如果在root中,那么直接取(分别取出上边存入的数据)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<s:debug></s:debug>
<h1>OGNL表达式:在OGNL表达式中,字符串要使用双引号括起来</h1>
<h2>if, elseif, else</h2>
<s:if test='#grade == "A"'>优秀</s:if>
<s:elseif test='#grade == "B"'>良好</s:elseif>
<s:else>未找到</s:else>

<br/>
<br/>
<h2>iterator</h2>
<s:iterator value="str" var="s">
	<s:property value="#s"/>
</s:iterator>
<hr/>

<s:iterator value="list">
	<s:property/>
</s:iterator>
<hr/>

<s:iterator value="map" var="entry">
	<s:property value="#entry.key"/>==<s:property value="#entry.value"/>
	
</s:iterator>
<hr/>

<s:iterator value="stu" var="s">
	<s:property value="#s.name"/>:<s:property value="#s.age"/>:<s:property value="#s.birthday"/>:<s:property value="#s.city"/>
</s:iterator>
</body>
</html>
    那么对于存取值总结一句话就是:
    1.访问contextMap中的数据,使用#
    2.访问root中的数据,直接写属性或者key值即可!

    对于struts的总结,那么大概也就这些,面试这些东西遇到的可能多点吧,当然,struts2只总结了很少一部分,还有标签,数据校验,文件上传下载,过滤器等,这些以后再慢慢补充吧!


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值