Struts2 总结

1、Struts2简单入门

1.1 struts2的概述

1.1.1 什么是Struts2?

在这里插入图片描述
★总结:struts2是一个基于MVC设计模式的WEB层框架。类似于servlet,但是相对于前端控制器等方面来说,两者有所区别。

1.1.2 使用Struts2的好处

1.web层的框架基于前端控制器的设计

在这里插入图片描述
2.struts的优势:
– 项目开源,使用及拓展方便,天生优势。
– 提供Exception处理机制
– 提供强大的、可以有效减页面代码的标签

1.2 struts2的入门使用

1.2.1 准备工作

1.下载struts2的开发环境
http://struts.apache.org/
2. 解压struts2的开发包解析文件用途
在这里插入图片描述

apps :Struts2提供的应用,war文件:web项目打成war包。直接放入到tomcat可以允许。
docs :Struts2的开发文档和API
lib :Strtus2框架的开发的jar包
src :Struts2的源码

1.2.2 创建Web项目,引入jar包

在这里插入图片描述

1.2.3 创建一个dome.jsp文件

<body>
	<h1>Struts2入门</h1>
	<h3><a href="${pageContext.request.contextPath }/hello.action">点击我执行</a></h3>
</body>

1.2.4 编写一个Action类并进行配置

public class HelloAction {
	/**
	 * 提供一个方法,方法名是固定的,不能传任何参数
	 * @return
	 */
	public String execute() {
		System.out.println("测试类执行了");
		return "success";
	}
}

对Action类配置

<?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>
	<!-- 配置Struts2常量,配置后在网页地址后必须加上.action才能访问 -->
	<constant name="struts.action.extension" value="action"/> 
	
	<!-- struts为了管理配置,进行包管理 -->
	<package name="demo" extends="struts-default" namespace="/">
		<!-- 配置action -->
		<action name="hello" class="com.test.HelloAction">
		
		<!-- 配置跳转页面 -->
		<result name="success">success.jsp</result>
		</action>
	</package>
</struts>

1.2.5 在web.xml文件中配置核心过滤器

<!-- 配置前端核心控制器 -->
  <filter>
  	<filter-name>struts2</filter-name>
  	<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  	<!-- 修改常量(常在struts.xml中配置) -->
  	<!-- <init-param>
  		<param-name>struts.action.extension</param-name>
  		<param-value>action</param-value>
  	</init-param> -->
  </filter>
  
  <filter-mapping>
  	<filter-name>struts2</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>

1.2.6 配置核心文件struts.xml

<?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>
	<!-- 配置Struts2常量,配置后在网页地址后必须加上.action才能访问 -->
	<constant name="struts.action.extension" value="action"></constant>
	
	<!-- 引入各个模块配置文件-->
	<include file="com/test/struts_demo1.xml"/>
</struts>

1.2.7 创建一个跳转success.jsp页面

<body>
	<h3>跳转成功</h3>
</body>

1.3 struts2的执行流程

在这里插入图片描述

当用户访问某一个Action的时候,先经过核心过滤器,在核心过滤器中执行一组拦截器(这组拦截器实现部分功能),执行目标Action,根据Action的返回值,进行页面跳转。

1.4 struts2的常见配置

1.4.1 Action的配置

package标签称为包,这个包与Java中的包的概念不一致。包为了更好管理action的配置。

  • package标签的属性
     name :包的名称,只有在一个项目中不重名即可。
     extends :继承哪个包,通常值为struts-default。
     namespace :名称空间,与标签中的name属性共同决定访问路径。
    > 名称空间有三种写法:
    ----- 带名称的名称空间 :namespace=”/aaa”
    ----- 跟名称空间 :namespance=”/”
    ----- 默认名称空间 :namespace=””

    abstract :抽象的,用于其他包的继承。

action标签配置Action类。

  • action标签的属性
     name :与namespace共同决定访问路径
     class :Action类的全路径
     method :执行Action中的哪个方法的方法名,默认值execute
     converter :用于设置类型转换器

1.4.2 常量的配置

在Struts2的框架中,提供了非常多的常量:(default.properties
struts.i18n.encoding=UTF-8 ----Struts2中所有的post请求的中文乱码不用处理。
struts.action.extension=action ----Struts2请求的默认的扩展名。默认扩展名是.action或者什么都不写。
在Struts2中修改一些常量的值:
修改常量的值,可以有三个位置进行修正
1.web.xml中进行修改

  <!-- 配置前端核心控制器 -->
  <filter>
  	<filter-name>struts2</filter-name>
  	<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  	<!-- 修改常量(常在struts.xml中配置) -->
  	<init-param>
  		<param-name>struts.action.extension</param-name>
  		<param-value>action</param-value>
  	</init-param>
  </filter>

2.struts.properties中进行修改

struts.action.extension=action

3.在struts.xml中进行修改

<constant name="struts.action.extension" value="action"></constant>

1.4.3 分模块开发配置

在struts.xml文件中引入Action类的配置文件

<!-- 引入各个模块配置文件-->
	<include file="com/test/struts_demo1.xml"/>

1.5 struts2的Action的编写

1.5.1 Action的编写的三种方式

1 Action类是一个POJO类
package com.test2;
/**
 * Action编写方式1:action是一个pojo类
 * @author 11312
 *
 */
public class ActionDemo1 {
	public String  execute() {
		System.out.println("Action编写方式1执行了");
		return null;
	}
}
2 Action类实现一个Action的接口
package com.test2;

import com.opensymphony.xwork2.Action;
/**
 * action编写方式2:实现action接口
 * @author 11312
 *
 */
public class ActionDemo2 implements Action{

	@Override
	public String execute() throws Exception {
		System.out.println("实现action接口的实现发方法实现了");
		return NONE;
	}
}
3 Action类继承ActionSupport类(常用)
package com.test2;

import com.opensymphony.xwork2.ActionSupport;
/**
 * action编写方法3:继承ActionSupport类
 * @author 11312
 *
 */
public class ActionDemo3 extends ActionSupport{

	public String execute() {
		System.out.println("action编写方法3:继承ActionSupport类,实现了");
		return NONE;
	}
}

1.5.2 Action的访问

1 通过method设置访问
<!-- 通过方法的方式访问 -->
		<action name="userFind" class="com.test3.UserAction" method="find"/>	
		<action name="userUpdate" class="com.test3.UserAction" method="update"/>
		<action name="userSave" class="com.test3.UserAction" method="save"/>
		<action name="userDelete" class="com.test3.UserAction" method="delete"/>
2通过通配符的方式进行配置(常用)
 <!--通过通配符访问 -->
		<action name="product_*" class="com.test3.ProductAction" method="{1}"/>	
3 通过动态方法访问
<!-- 动态访问 -->
		<action name="customer" class="com.test3.CustomerAction"/>	
开启动态访问
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>

三种方式的访问路径

<h1>Action的访问</h1>
<h3>通过method方式</h3>
<a href="${ pageContext.request.contextPath }/userFind.action">查询用户</a><br/>
<a href="${ pageContext.request.contextPath }/userUpdate.action">修改用户</a><br/>
<a href="${ pageContext.request.contextPath }/userDelete.action">删除用户</a><br/>
<a href="${ pageContext.request.contextPath }/userSave.action">保存用户</a><br/>

<h3>通过通配符的方式</h3>
<a href="${ pageContext.request.contextPath }/product_find.action">查询商品</a><br/>
<a href="${ pageContext.request.contextPath }/product_update.action">修改商品</a><br/>
<a href="${ pageContext.request.contextPath }/product_delete.action">删除商品</a><br/>
<a href="${ pageContext.request.contextPath }/product_save.action">保存商品</a><br/>

<h3>通过动态方法访问的方式</h3>
<a href="${ pageContext.request.contextPath }/customer!find.action">查询客户</a><br/>
<a href="${ pageContext.request.contextPath }/customer!update.action">修改客户</a><br/>
<a href="${ pageContext.request.contextPath }/customer!delete.action">删除客户</a><br/>
<a href="${ pageContext.request.contextPath }/customer!save.action">保存客户</a><br/>

2. struts2数据的封装和servlet的API的访问

2.1 Struts2的Servlet的API的访问

1.完全解耦合的方式:只能访问雨中的数据(**)
 >编写jsp
<h1>struts2的servlet的API访问方式一:完全解耦合方式</h1>
	<form action="${pageContext.request.contextPath }/ActionDemo1.action" method="post">
		用户:<input type="text" name="name"><br>
		密码:<input type="password" name="password"><br>
		<input type="submit" value="提交">
	</form>
 >编写Action
/**
 * 方式1:通过完全解耦合方式
 * @author 11312
 *
 */
public class ActionDemo1 extends ActionSupport{

	@Override
	public String execute() throws Exception {
		//一、接收参数
		//利用struts2中的actionContext对象
		ActionContext context = ActionContext.getContext();
		//调用actionContext中的方法
		Map<String, Object> map = context.getParameters();//类似于request.getParameterMap();
		//遍历对象中的数据
		for (String key : map.keySet()) {
			String[] values =  (String[]) map.get(key);
			System.out.println(key + "   "+Arrays.toString(values));
		}
		//二、向域中对象存入数据
		context.put("reqName", "reqValue");//相当于request.setAttribute();
		context.getSession().put("sessName", "sessValue");//相当于session.setAttribute();
		context.getApplication().put("appName", "appValue");//相当于application.setAttribute();
		return "success";
	}
}

***注意:这种方式只能获得代表request、session、application的数据的Map集合,不能操作这些对象的本身的方法。

2.原生的方式:既可以操作数据,也可以获得方法(**)
>jsp页面
<h1>struts2的servlet的API访问方式二:servlet的API的原生方式</h1>
	<form action="${pageContext.request.contextPath }/ActionDemo2.action" method="post">
		用户:<input type="text" name="name"><br>
		密码:<input type="password" name="password"><br>
		<input type="submit" value="提交">
	</form>
>Action页面
package com.demo1;

import java.util.Arrays;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
/**
 * 方式二:servlet原生API方式
 */
public class ActionDemo2 extends ActionSupport{

	@Override
	public String execute() throws Exception {
		//一、接收数据
		HttpServletRequest 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));
		}
		//二、向域中存取数据
		request.setAttribute("reqName", "reqValue");
		request.getSession().setAttribute("sessName", "名字");
		ServletActionContext.getServletContext().setAttribute("appName", "appValue");
		return super.execute();
	}
}

***注意:这种方式可以操作域对象的数据,同时也可以获得对象的方法

3.接口注入方式(了解)

编写jsp

<h1>struts2的servlet的API访问方式三:接口注入方式</h1>
	<form action="${pageContext.request.contextPath }/ActionDemo3.action" method="post">
		用户:<input type="text" name="name"><br>
		密码:<input type="password" name="password"><br>
		<input type="submit" value="提交">
	</form>

编写Action

package com.demo1;

import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.util.ServletContextAware;

import com.opensymphony.xwork2.ActionSupport;
/**
 * 方式三:使用接口注入方式
 * @author 11312
 *
 */
public class ActionDemo3 extends ActionSupport implements ServletRequestAware,ServletContextAware{

	private HttpServletRequest request;
	private ServletContext context;

	@Override
	public String execute() throws Exception {
		//一、接收数据
		//通过接口注入获得request对象
		Map<String, String[]> map = request.getParameterMap();
		for (String key : map.keySet()) {
			String[] values = map.get(key);
			System.out.println(key+"   "+values);
		}
		
		//二、向域中存入数据
		request.setAttribute("reqName", "reqValue");
		request.getSession().setAttribute("sessName", "sessValue");
		context.setAttribute("appName", "appvalue");
		return super.execute();
	}
	
	public void setServletRequest(HttpServletRequest request) {
		this.request=request;
	}
	@Override
	public void setServletContext(ServletContext context) {
		this.context = context;
	}
}

Servlet是单例的,多个程序访问同一个Servlet只会创建一个Servlet的实例。Action是多例的,一次请求,创建一个Action的实例(不会出现线程安全的问题)。

2.2 Struts2的结果页面配置

1.结果页面分类:
	全局结果页面:全局结果页面指的是,在包中配置一次,其他的在这个包中的所有的action只要返回了这个值,都可以跳转到这个页面。
		针对这个包下的所有的action的配置都有效。
<package name="demo1" extends="struts-default" namespace="/">
		<global-results>
			<result name="success">/demo1/success.jsp</result>
		</global-results>
			<action name="ActionDemo1" class="com.demo1.ActionDemo1" >
			</action>
			<action name="ActionDemo2" class="com.demo1.ActionDemo2" >
			</action>
			<action name="ActionDemo3" class="com.demo1.ActionDemo3" >
			</action>
		</package>
	局部结果页面:局部结果页面指的是,只能在当前的action中的配置有效。
		针对当前的action有效
<package name="demo1" extends="struts-default" namespace="/">
		<global-results>
			<result name="success">/demo1/success.jsp</result>
		</global-results>
			<action name="ActionDemo1" class="com.demo1.ActionDemo1" >
				<result name="success">/demo1/success.jsp</result>
			</action>
			<action name="ActionDemo2" class="com.demo1.ActionDemo2" >
			</action>
			<action name="ActionDemo3" class="com.demo1.ActionDemo3" >
			</action>
		</package>
2.result标签的配置(**)	
  • result标签用于配置页面的跳转。在result标签上有两个属性:
    – name属性 :逻辑视图的名称。默认值:success
    – type属性 :页面跳转的类型。值如下 :
    -------- dispatcher :默认值,请求转发。(Action转发JSP)
    -------- redirect :重定向。(Action重定向JSP)
    -------- chain :转发。(Action转发Action)
    -------- redirectAction :重定向。(Action重定向Action)
    -------- stream :Struts2中提供文件下载的功能。

2.3 Struts2的数据封装

属性驱动

1.提供set方法的方式(少用)
2.页面提供OGNL表达式方式
Action类
在这里插入图片描述
jsp
在这里插入图片描述
3.模型驱动(重点)
Action类
在这里插入图片描述
jsp
在这里插入图片描述

模型驱动方式最常用的方式:
缺点:只能同时向一个对象中封装数据。
使用第二种可以向多个对象中同时封装数据:

2.4 Struts2的INPUT逻辑视图的配置

Action接口中提供了五个逻辑视图的名称:
 SUCCESS
 ERROR
 LOGIN
 INPUT :input在某些拦截器中会使用。
 NONE

2.5 Struts2的复杂类型的数据封装(了解)

1.封装到List集合
jsp

在这里插入图片描述

Action
在这里插入图片描述
2.封装到Map集合
jsp
在这里插入图片描述
Action
在这里插入图片描述

3 OGNL&ValueStack

3.1OGNL表达式

3.1.1什么是OGN表达式?

OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。可以代替EL表达式功能。

3.1.2 OGNL的作用

  • 支持对象方法调用
  • 支持类静态方法调用和值访问,表达式格式 @[类全名(包括包路径)]@[方法名|值名]
  • 支持赋值操作和表达式串联
  • 访问OGNL上下文和ActionContext
  • 操作集合对象

3.1.3 OGNL三要素

1.表达式(做什么)
2.根对象(谁操作)
3.Context对象(在那里执行),在表达式访问Context中的对象,需要使用“#”号加上对象名

3.1.4 OGNL表达式使用入门

1.使用OGNL表达式准备工作

导包(struts2的包中包含OGNL的jar包)

2.编写demo1.jsp文件
需要映入taglib标签。struts2中只有一个标签就是<%@ taglib uri="/struts-tags" prefix=“s” %>

3.编写Action类

4.编写跳转后的页面(该页面中会使用OGNL表达式获取值栈中的值)

5.OGNL表达式可以在jsp,xml,properties等文件中使用

3.2 ValueStack(栈中的数据在任何地方都可取)

3.2.1 什么是值栈?

ValueStack实际上就是一个容器。它由Struts框架创建,当前端页面如jsp发送一个请求时,Struts的默认拦截器会将请求中的数据进行封装,并入ValueStack的栈顶。

valueStack其实类似一个数据中转站(Struts2的框架当中的数据就会都保存到了ValueStack中)。
	- 	ValueStack接口,实现类OgnlValueStack对象 
	-   ValueStack贯穿整个Action的生命周期。(Action对象一旦被创建,框架就会创建一个ValueStack对像)

3.2.2 值栈的内部结构

Value Stack主要有两个主要的区域:

  • root区域:其实就是一个ArrayList。里面一般放对象。获取root的数据不需要加#号
  • context区域:其实就是一个Map。里面放置的是web开发的常用的对象数据的引用。获取context数据需要加#号。
    • request
    • session
    • application
    • parameters
    • attr
      在这里插入图片描述

3.2.3 ActionContext和ValueStack的

servletContext:servlet 的上下文
ActionContext:Action的上下文
- 通过源码查看到:当请求过来的时候,执行过滤器中的doFilter方法,在这个方法中创建ActionContext 过程中,创建ValueStack对象,将ValueStack对象传递给ActionContext对象。所以可以通过ActionContext获取值栈对象
- ActionContext对象之所以能够访问Servlet的API(访问是与对象的数据)。因为在七内部有值栈可以引用。

3.2.4 获取值栈对象

1.通过ActionContext获取

//一种:通过ActionContext获取
ValueStack ValueStack1 = ActionContext.getContext().getValueStack();

2.通过request获取

//2通过request获取
ValueStack ValueStack1 = ServletActionContext.getContext().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);

两者获取的是同一个对象,因为在ActionContext获取到数据的时候会传递给request一份。一个Action对象只会有一个ValueStack

3.2.5 操作值栈

1.在Action中提供属性的get方法的方式
– 默认的情况下,将Action对象压入值栈
Action类:

/**
 * 操作值栈中的值:方式一:在Action对象中提供属性的get方法
 * @author 11312
 *
 */
public class ValueStackDemo1 extends ActionSupport{
	//提供get方法
	private User  user;
	public User getUser() {
		return user;
	}

	@Override
	public String execute() throws Exception {
		//向ValueStack中存值
		user = new User("望山","12354");
		return SUCCESS;
	}
}

jsp获取值栈数据:

<s:debug></s:debug>
<-- 方式一的获取:利用Action在值栈中的特性-->
<s:property value="user.username"/>
<s:property value="user.password"/>

2.使用ValueStack中本身的方法的方式(常用)
Action类:

/**
 * 操作值栈中的值:方式二 :在Action对象中提供属性的get方法
 * @author 11312
 *
 */
public class ValueStackDemo2 extends ActionSupport{
	
	@Override
	public String execute() throws Exception {
		
		//获取值栈对象
		ValueStack valueStack = ActionContext.getContext().getValueStack();
		//使用 push(Object obj); 或  set(String key,Object obj); 方式,向ValueStack中存值
		User user = new User("望山","12354");
		//现在user在栈顶
		valueStack.push(user);
		//现在name在栈顶
		valueStack.set("name", "张");
		return SUCCESS;
	}
}

jsp获取值栈数据:

<!-- 方式二调用值栈方法实现 -->
<s:property value="username"/>
<s:property value="password"/>
<s:property value="name"/>

3.2.6 从值栈中获取数据

获取值栈中的数据就是在页面中使用OGNL表达式

  • 获取root的数据,不需要加#号
  • 获取context数据,需要加#号

1.获取一个对象数据
jsp获取值栈数据:

<!-- 获取一个对象数据 -->
<s:property value="username"/>
<s:property value="password"/>

2.获取一个集合数据
Action:

//向值栈中保存一个集合
List<User> list = new ArrayList<User>();
list.add(new User("aa","11"));
list.add(new User("bb","22"));
list.add(new User("cc","33"));
ActionContext.getContext().getValueStack().set.("list",list);

//想context中存
ServletActionContext.getRequest().setAttribute("name","wang1");
ServletActionContext.getRequest().getSession().setAttribute("name","wang2");
ServletActionContext.getServletContext().setAttribute("name","wang3");

jsp:

<!-- 获取集合数据 -->
<s:property value="list[0].username"/>
<s:property value="list[0].password"/>
<s:property value="list[1].username"/>
<s:property value="list[1].password"/>
<s:property value="list[2].username"/>
<s:property value="list[2].password"/>

<!-- 获取context中数据 -->
<s:property value="#request.name"/>
<s:property value="#session.name"/>
<s:property value="#application.name"/>
<!-- 接收参数 -->
<s:property value="#parameters.id"/>

3.2.7 EL能够访问值栈

原因: 因为Struts2的框架的底层对request.getAttribute(String name);

3.2.8 OGNL表达式特殊字符

1.#
获取context中的数据

<h1>#号用法</h1>
<h3>获取context的数据</h3>
<%
	request.setAttribute("name", "wang");
%>
<s:property value="#request.name"/>

<h3>构建map结合</h3>
<s:iterator  var="i" value="{'aa','bb','cc'}">
	<s:property value="i"/>--<s:property value="#i"/><br>
</s:iterator>
<s:iterator  value="{'aa':'11','bb':'21','cc':'31'}">
	<s:property value="key"/>--<s:property value="value"/><br>
</s:iterator>

<s:radio list="{'',''}" name="gender" label="性别" />

2.%
强制解析OGNL()

<%
	request.setAttribute("name", "wang");
%>
姓名:<s:textfield name="name" value="%{#request.name}"/>

3.$
在配置文件中使用OGNL

  • 属性文件
    • 国际化地方 配置.properties
    • user.Welcome = 欢迎,${#session.user.username}
  • xml文件
    • 文件下载 filename=${文件名}

Struts2 的拦截器(*****)

拦截器的概述

1.什么是拦截器

  • Interceptor:拦截器,起到拦截Action的作用。
    Filter:过滤器,过滤从客户端向服务器发送的请求。
    Interceptor:拦截器,拦截是客户端对Action的访问。更细粒度化的拦截。(拦截 Action中的具体的方法)。
    -Struts2框架核心的功能都是依赖拦截器实现。

2.Struts2的执行流程

客户端向服务器发送一个Action的请求,执行核心过滤器(doFilter)方法。在这个方法中,调用executeAction()方法,在这个方法内部调用dispatcher.serviceAction();在这个方法内部创建一个Action代理,最终执行的是Action代理中的execute(),在代理中执行的execute方法中调用ActionInvocation的invoke方法。在这个方法内部递归执行一组拦截器(完成部分功能),如果没有下一个拦截器,就会执行目标Action,根据Action的返回的结果进行页面跳转。
在这里插入图片描述

拦截器入门

1.搭建Strtus2的环境
2.编写拦截器类
 编写一个类实现Interceptor接口或者继承AbstractInterceptor类。

/**
 * 自定义的拦截器一
 * @author jt
 *
 */
public class InterceptorDemo1 extends AbstractInterceptor{

	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		System.out.println("InterceptorDemo1执行了...");
		String obj = invocation.invoke();
		System.out.println("InterceptorDemo1执行结束了...");
		return obj;
	}

}

3.对拦截器进行配置
定义拦截器进行配置
在这里插入图片描述
定义一个拦截器栈的方式
在这里插入图片描述

CRM的权限拦截器

实现用户登录的共能

1.创建表和实体
创建表

CREATE TABLE `sys_user` (
  `user_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `user_code` varchar(32) NOT NULL COMMENT '用户账号',
  `user_name` varchar(64) NOT NULL COMMENT '用户名称',
  `user_password` varchar(32) NOT NULL COMMENT '用户密码',
  `user_state` char(1) NOT NULL COMMENT '1:正常,0:暂停',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

2.创建实体
在这里插入图片描述
3.提交数据到Action
在这里插入图片描述
4.Action–>Service–>DAO
编写Service
在这里插入图片描述
编写DAO
在这里插入图片描述
5.根据结果进行页面跳转
在这里插入图片描述

实现权限拦截器

1.编写权限拦截器
在这里插入图片描述
2.配置权限拦截器
在这里插入图片描述

Struts2的标签库

通用的标签

在这里插入图片描述
判断标签<s:if>、<s:elseif>、<s:esle>
在这里插入图片描述
 <s:iterator>
在这里插入图片描述
其他常用的标签
 <s:property/>
 <s:debug/>
 <s:date />----在页面上进行日期格式化。

UI标签(方便数据回显)

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Struts2面试题包括以下内容: 1. SpringMVC与Struts2的主要区别。 2. Struts2中如何访问HttpServletRequest、HttpSession和ServletContext三个域对象? 3. Struts2中的拦截器有什么用途? 4. Struts2中的默认包struts-default有什么作用? 5. Struts2中,Action并没有直接收到用户的请求,那它为什么可以处理用户的请求?又凭什么知道一个请求到底交给哪一个Action来处理? 6. Struts2中,Action通过什么方式获取用户从页面输入的数据,又是通过什么方法把数据传给视图层显示的? 7. struts2的执行流程。 8. 具有相同名称的一组值,struts2如何实现封装? 9. 简述struts2值栈的原理和生命周期? 10. 简述Struts2异常处理机制? 11. 谈一下你的项目选择Struts2的理由? 12. 阐述Struts2中的Action如何编写,是否采用单例?[1] Struts2是一个经典的MVC框架,与Struts1相比,有以下区别: 1. 核心控制器改成了过滤器,比Servlet的级别要高。 2. Struts1要求业务类必须继承Action或dispatchAction,而Struts2只需要提供一个POJO类。 3. 绑定值到业务类时,Struts1是通过ActionForm,而Struts2是通过模型或属性驱动直接绑定到Action属性。 4. Struts1严重依赖于Servlet的API,而Struts2则脱离了Servlet的API。 5. 管理Action时,Struts1是单例模式,而Struts2是每个请求产生一个实例。 6. 在表达式的支持上,Struts2不仅有JSTL,还有功能更加强大的OGNL表达式。 7. Struts1的类型转换是单向的,而Struts2是双向的。 8. Struts2提供了拦截器,可以在访问Action之前或之后增加如权限拦截等功能。 9. Struts2提供了国际化资源文件管理实现。 10. Struts2支持多种视图类型,如JSP、Freemarker、Velocity等。[2] 在使用Struts2时,可能会遇到一些常见的问题,例如: 1. 表单重复提交的问题可以通过使用令牌机制来解决。 2. 国际化必须经过Action来实现。 3. 使用模型驱动时,可能会出现地址内存不一致的问题,可以通过对象拷贝来解决。 4. 在页面使用转发时可能会报404错误,可以通过过滤器改变请求地址来解决。 5. 在使用字符串时需要注意使用双引号而不是单引号。 6. 当校验出错时,需要跳转到相应的页面,可以使用通配符来解决。[3] 总结起来,Struts2面试题主要涉及Struts2与其他框架的区别、Struts2的核心概念和特性,以及在实际使用中可能遇到的问题和解决方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值