一 Struts框架(上)
Struts2 是基于MVC的WEB框架
经过六年多的发展,Struts1已经成为了一个高度成熟的框架,不管是稳定性还是可靠性都得到了广泛的证明。市场占有率超过20%,拥有丰富的开发人群,几乎已经成为了事实上的工业标准。但是随着时间的流逝,技术的进步,Struts1的局限性也越来越多地暴露出来,并且制约了Struts1的继续发展。
对于Struts1框架而言,由于与JSP/Servlet耦合非常紧密,因而导致了一些严重的问题。首先,Struts1支持的表现层技术单一。由于Struts1出现的年代比较早,那个时候没有FreeMarker、Velocity等技术,因此它不可能与这些视图层的模版技术进行整合。其次,Struts1与Servlet API的严重耦合,使应用难于测试。最后,Struts1代码严重依赖于Struts1 API,属于侵入性框架。
从目前的技术层面上看,出现了许多与Struts1竞争的视图层框架,比如JSF、Tapestry和spring MVC等。这些框架由于出现的年代比较近,应用了最新的设计理念,同时也从Struts1中吸取了经验,克服了很多不足。这些框架的出现也促进了Struts的发展。
Struts已经分化成了两个框架:第一个是在传统的Struts1的基础上,融合了另外的一个优秀的Web框架WebWork的Struts2。Struts 2虽然是在Struts1的基础上发展起来的,但是实质上是以WebWork为核心的。Struts2为传统的Struts1注入了WebWork的先进的设计理念,统一了Struts1和WebWork两个框架。
官网下的jar包
打开看见这是apache和opensymphony的WebWork结合的一个产品
找到struts-2.3.16.3\apps路径下的struts2-blank.war这个包参考写代码
1参考上面的war包创建Web动态工程导入相关jar包
参考xml。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
然后在src下放一个struts.xml,参考得来下面的
这是最简单的struts.xml配置
其效果是当访问index路径的时候,服务端跳转到index.jsp
<?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>
<package name="default" namespace="/" extends="struts-default">
<action name="index">
<result>index.jsp</result>
</action>
</package>
</struts>
2开始写HelloWorld
修改一下inde.jsp页面
运行产生效果
通过这个过程体会到
相当于实现了servlet的服务端跳转到index.jsp的功能
3整个流程
4 继续 struts 显示数据到JSP
Model层使用一个简单的Product用于存放数据
public class Product {
int id;
String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
ProductAction用于控制
import com.tzy.struts.Product;
public class ProductAction {
private Product product;
public String show() {
product = new Product();
product.setName("xiaomi8");
return "show";
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
}
在struts.xml中配置跳转
该配置表示 访问路径/showProduct会调用 ProductAction 类的 show 方法
服务端跳转到show.jsp
<action name="showProduct" class="com.tzy.struts.action.ProductAction" method="show">
<result name="show">show.jsp</result>
</action>
show.jsp
在web目录下创建show.jsp文件
通过EL表达式,取出product的name
注: ${product}会访问对应的Action的 getProduct()方法
注: 严格地说,是Struts通过getProudct()方法返回product对象,然后再把product对象通过request.setAttribute("product", product) 放在"product" 这个key上,这样就方便EL表达式去取出来了
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${product.name}
</body>
</html>
5整个流程
- 访问路径 /showProduct
- 所有访问都被struts的filter所拦截,并进入struts的工作流程
- 根据配置文件struts.xml, 会执行ProductAction的show方法
- 在show方法中,将实例属性product指向一个新的对象,并设置名称为xiaomi8
- 服务端跳转到show.jsp
- 在show.jsp中,访问ProductAction.getProduct() 获取实例属性product,并显示其名称xiaomi8
6 struts 提交数据到ACTION
准备提交数据的jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>submit</title>
</head>
<body>
<form action="addProduct">
<input type="text" name="product.name">
<br/>
<input type="submit" value="submit">
</form>
</body>
</html>
为addProduct路径配置对应的action和方法以及返回
<action name="addProduct" class="com.tzy.struts.action.ProductAction" method="add">
<result name="show">show.jsp</result>
</action>
在ProductAction添加add方法
public String add(){
System.out.println("product.name:"+product.getName());
return "show";
}
7 原理图
- 访问路径 /addProduct
- 所有访问都被struts的filter所拦截,并进入struts的工作流程
- 根据配置文件struts.xml, 会执行ProductAction的add方法
- 在add方法执行之前,Struts生成一个新的product对象,并把页面传递过来的name设置在该对象上,接着把该对象通过setProduct()方法,注入ProductAction
- 服务端跳转到show.jsp
- 在show.jsp中,访问ProductAction.getProduct() 获取注入的product,并显示其名称
8 struts 中文问题
Struts的中文问题,由3部分组成
- jsp提交数据的时候,必须是UTF-8编码的
- struts拿到数据后进行UTF-8解码
- 服务端跳转到jsp进行显示的时候,要指定浏览器使用UTF-8进行显示
UTF-8可以换成GBK或者GB2312,但是必须统一,不能混用
使用上一步的操作传入啦啦啦
修改提交页面
修改展示页面
修改struts.xml文件
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
再次测试
8 struts 启动失败,出现错误ERROR FILTERSTART 应该如何调试
在tomcat启动struts web应用的时候,如果出现了struts配置上的错误,你可能只能看到一个 Error FilterStart的提示,而看不到详细的错误原因。
这样就加大了定位和解决问题的难度
这是因为默认配置下,struts把日志输出关闭了
为了把日志输出开启便于调试,需要增加log4j.xml这个配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration PUBLIC "-//log4j/log4j Configuration//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p %c.%M:%L - %m%n"/>
</layout>
</appender>
<!-- specify the logging level for loggers from other libraries -->
<logger name="com.opensymphony">
<level value="DEBUG" />
</logger>
<logger name="org.apache.struts2">
<level value="DEBUG" />
</logger>
<!-- for all other loggers log only debug and above log messages -->
<root>
<priority value="INFO"/>
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>
这样struts就会启动失败,虽然启动失败了,但是tomcat给出的错误信息非常有限,很不利于调试。 无法知道到底哪里写错了。
然后重新启动tomcat即可看到具体struts启动失败错误原因
如图所示,可以看到很明确的错误原因,ProductAction类的ClassNotFoundException
关闭log4j.xml日志输出
有了log4j.xml日志输出可以帮助调试,但是也会导致struts的启动变慢。
关闭log4j.xml日志输出很简单,直接把log4j.xml命名成其他文件即可,以后要用再把名字改回来,很方便
9 在struts中也可以获取servlet包中的request和response对象
修改ProductAction的show方法,获取request和response对象
public String show(){
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
System.out.println("request:\t" + request);
System.out.println("response:\t" + response);
Product product = new Product();
product.setName("xiaomi8");
return "show";
}
在Tomcat的控制台输出 可以看到Struts使用类StrutsRequestWrapper对HttpServletRequest进行了封装
10 struts 获取SESSION对象
- struts中的Session有两个
- 一个是传统的servlet包下的HttpSession
- 另一个是Struts中自己定义的Session
- 传统的servlet包下的session的获取办法是:
- ServletActionContext.getRequest().getSession();
- 使用该方法,需要在eclipse的项目中导入servlet-api.jar,可以在右边下载
- 新的Session的获取办法是
- Map m = ActionContext.getContext().getSession();
- 这个session以Map类的形式出现,其中的值和HttpSession中的值是同步的
修改ProductAction的add方法中访问Session
public String add(){
Map m = ActionContext.getContext().getSession();
m.put("name", product.getName());
return "show";
}
在show.jsp中把通过EL表达式把session中的数据取出来
通过
http://127.0.0.1:8080/addProduct.jsp
增加数据
在show.jsp中就可以看到session中的name
11 省略上传下载
一 Struts框架(上)的更多相关文章
- Struts框架 内部资料 请勿转载 谢谢合作
Struts框架 struts框架具有组件的模块化,灵活性和重用性的优点,同时简化了基于MVC的web应用程序的开发. 本章详细讨论struts架构.我们将看到struts是如何清晰地区分控制,事务逻 ...
- Struts框架详解
1.Struts应用框架介绍 (1)框架 框架最简单的形式是指已开发过并已测试过的软件的程序块,这些程序块可以在多个软件开发工程中重用.框架提供了一个概括的体系结构模版,可以用这个模板来构建特定领域中 ...
- Struts 框架 之 文件上传下载案例
Struts 框架 文件上传 1. 先准备 Struts 环境 (我使用的是struts 2.3.4版本) 导jar包:
- Struts框架的核心业务
Struts的核心业务 Struts核心业务有很多,这里主要介绍了比较简单一些的: 请求数据的处理,和数据自动封装,类型自动转换 1.Struts中数据处理 1.1.方式1:直接过去servletap ...
- 使用Struts框架,实现用户登陆功能
前言:本篇文章是本人这周学习的一个小结,在自我总结的同时,希望也能够给其他同学带来一点帮助.本文主要知识是参照书本上的知识点以及网上其他博客文章,在上机操练后的所得,具体源码主要来自http://bl ...
- Struts框架2ActionError类 内部资料 请勿转载 谢谢合作
ActionError类从不独立进行错误处理,它们总是被存储在ActionErrors对象中.ActionErrors对象保存ActionError类的集合以及它们特定的属性值,我们可以使用自己定义的 ...
- struts框架学习过程中的问题
1,错误: java.lang.NullPointerException: Module 'null' not found.错误原因,struts运行需要的.jar文件拷贝不足,应该把它们加入到cla ...
- struts(三)——struts框架实现登录示例
前两篇讲解了struts框架的基本实现,自己感觉讲的也有些枯燥,今天拿登录的例子来做一个实现. 1.新建一个javaweb项目,并将struts的jar包拷贝到WebRoot/WEB-INF/lib下 ...
- struts(二)——struts框架实现的基本原理
上一篇文章,我们介绍了MVC框架的基本原理,并指出了这个基本框架中存在大量if…else的问题.今天我们来介绍一下struts框架,让struts解决这个问题. 首先,看一下粗略的时序图: Actio ...
随机推荐
- TCP/IP三次握手和四次挥手
原博链接:https://www.cnblogs.com/Andya/p/7272462.html
- [原][算法][earth]三段smooth,传入时间,返回距离。仿谷歌视角飞跃处理
算法需求: 传入[0~1]的时间time,返回[0~1]的路程. 整个路程distance[0~1]分为三段路径: 第一段:在0.25time的时间里,速度从0,位置从distance:0加速移动到距 ...
- [Hibernate] official tutorial - userguide
Persistence contexts org.hibernate.Session API and javax.persistence.EntityManager API represent a c ...
- [数据结构]P1.3 栈 Stack
* 注: 本文/本系列谢绝转载,如有转载,本人有权利追究相应责任. 栈是一种先进后出的结构(FILO),常见的操作有:push 入栈.pop删除栈顶元素并返回.peek 查看栈顶元素 与其他线性结构一 ...
- PAC-based methods
PAC 主成分分析 主要的几个步骤: 线性变换,线性无关,主要线性分量(方差加大的方向),求主要线性分量的表达式 其中线性变换的概念(一个矩阵与一个列向量A相乘,等到一个新的列向量B,则称该矩阵为列向 ...
- 安卓MVP框架
一.理解MVP 原文地址 我的Demo 效果图: 项目结构: 实现 一.Model层 首先定义一个实体类User package app.qcu.pmit.cn.mvpdemo.model; /** ...
- httpd常见配置
httpd常见配置 配置文件 /etc/httpd/conf/httpd.conf 主配置文件 /etc/httpd/conf.d/*.conf 辅助配置文件 配置文件语法检查及重新加载配置文 ...
- eslint详细配置
vue-cli3按照官网教程配置搭建后,发现每次编译,eslint都抛出错误, 修改配置在 .eslintrc.js中修改 或者 关闭eslint 1.关闭eslint 直接注释掉package ...
- 一个简单CI/CD流程的思考
因为公司有两地研发团队,在统一CI/CD上难度不亚于两家公司合并后的新流程建立,并非不可攻克,简单描述下心得. 首先,代码管理使用gerrit -> 因其强大的 codereview 功能被选中 ...
- js获取谷歌浏览器版本
根据浏览器的useragent获取浏览器信息 // 获取谷歌浏览器版本 function getChromeVersion() { var arr = navigator.userAgent.spli ...