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整个流程

  1. 访问路径 /showProduct
  2. 所有访问都被struts的filter所拦截,并进入struts的工作流程
  3. 根据配置文件struts.xml, 会执行ProductAction的show方法
  4. 在show方法中,将实例属性product指向一个新的对象,并设置名称为xiaomi8
  5. 服务端跳转到show.jsp
  6. 在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 原理图

  1. 访问路径 /addProduct
  2. 所有访问都被struts的filter所拦截,并进入struts的工作流程
  3. 根据配置文件struts.xml, 会执行ProductAction的add方法
  4. 在add方法执行之前,Struts生成一个新的product对象,并把页面传递过来的name设置在该对象上,接着把该对象通过setProduct()方法,注入ProductAction
  5. 服务端跳转到show.jsp
  6. 在show.jsp中,访问ProductAction.getProduct() 获取注入的product,并显示其名称

8 struts 中文问题

Struts的中文问题,由3部分组成

  1. jsp提交数据的时候,必须是UTF-8编码的
  2. struts拿到数据后进行UTF-8解码
  3. 服务端跳转到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框架(上)的更多相关文章

  1. Struts框架 内部资料 请勿转载 谢谢合作

    Struts框架 struts框架具有组件的模块化,灵活性和重用性的优点,同时简化了基于MVC的web应用程序的开发. 本章详细讨论struts架构.我们将看到struts是如何清晰地区分控制,事务逻 ...

  2. Struts框架详解

    1.Struts应用框架介绍 (1)框架 框架最简单的形式是指已开发过并已测试过的软件的程序块,这些程序块可以在多个软件开发工程中重用.框架提供了一个概括的体系结构模版,可以用这个模板来构建特定领域中 ...

  3. Struts 框架 之 文件上传下载案例

    Struts 框架 文件上传 1. 先准备 Struts 环境 (我使用的是struts 2.3.4版本) 导jar包:

  4. Struts框架的核心业务

    Struts的核心业务 Struts核心业务有很多,这里主要介绍了比较简单一些的: 请求数据的处理,和数据自动封装,类型自动转换 1.Struts中数据处理 1.1.方式1:直接过去servletap ...

  5. 使用Struts框架,实现用户登陆功能

    前言:本篇文章是本人这周学习的一个小结,在自我总结的同时,希望也能够给其他同学带来一点帮助.本文主要知识是参照书本上的知识点以及网上其他博客文章,在上机操练后的所得,具体源码主要来自http://bl ...

  6. Struts框架2ActionError类 内部资料 请勿转载 谢谢合作

    ActionError类从不独立进行错误处理,它们总是被存储在ActionErrors对象中.ActionErrors对象保存ActionError类的集合以及它们特定的属性值,我们可以使用自己定义的 ...

  7. struts框架学习过程中的问题

    1,错误: java.lang.NullPointerException: Module 'null' not found.错误原因,struts运行需要的.jar文件拷贝不足,应该把它们加入到cla ...

  8. struts(三)——struts框架实现登录示例

    前两篇讲解了struts框架的基本实现,自己感觉讲的也有些枯燥,今天拿登录的例子来做一个实现. 1.新建一个javaweb项目,并将struts的jar包拷贝到WebRoot/WEB-INF/lib下 ...

  9. struts(二)——struts框架实现的基本原理

    上一篇文章,我们介绍了MVC框架的基本原理,并指出了这个基本框架中存在大量if…else的问题.今天我们来介绍一下struts框架,让struts解决这个问题. 首先,看一下粗略的时序图: Actio ...

随机推荐

  1. TCP/IP三次握手和四次挥手

    原博链接:https://www.cnblogs.com/Andya/p/7272462.html

  2. [原][算法][earth]三段smooth,传入时间,返回距离。仿谷歌视角飞跃处理

    算法需求: 传入[0~1]的时间time,返回[0~1]的路程. 整个路程distance[0~1]分为三段路径: 第一段:在0.25time的时间里,速度从0,位置从distance:0加速移动到距 ...

  3. [Hibernate] official tutorial - userguide

    Persistence contexts org.hibernate.Session API and javax.persistence.EntityManager API represent a c ...

  4. [数据结构]P1.3 栈 Stack

    * 注: 本文/本系列谢绝转载,如有转载,本人有权利追究相应责任. 栈是一种先进后出的结构(FILO),常见的操作有:push 入栈.pop删除栈顶元素并返回.peek 查看栈顶元素 与其他线性结构一 ...

  5. PAC-based methods

    PAC 主成分分析 主要的几个步骤: 线性变换,线性无关,主要线性分量(方差加大的方向),求主要线性分量的表达式 其中线性变换的概念(一个矩阵与一个列向量A相乘,等到一个新的列向量B,则称该矩阵为列向 ...

  6. 安卓MVP框架

    一.理解MVP 原文地址 我的Demo 效果图: 项目结构: 实现 一.Model层 首先定义一个实体类User package app.qcu.pmit.cn.mvpdemo.model; /** ...

  7. httpd常见配置

    httpd常见配置 配置文件 /etc/httpd/conf/httpd.conf    主配置文件 /etc/httpd/conf.d/*.conf  辅助配置文件 配置文件语法检查及重新加载配置文 ...

  8. eslint详细配置

    vue-cli3按照官网教程配置搭建后,发现每次编译,eslint都抛出错误, 修改配置在 .eslintrc.js中修改   或者  关闭eslint 1.关闭eslint 直接注释掉package ...

  9. 一个简单CI/CD流程的思考

    因为公司有两地研发团队,在统一CI/CD上难度不亚于两家公司合并后的新流程建立,并非不可攻克,简单描述下心得. 首先,代码管理使用gerrit -> 因其强大的 codereview 功能被选中 ...

  10. js获取谷歌浏览器版本

    根据浏览器的useragent获取浏览器信息 // 获取谷歌浏览器版本 function getChromeVersion() { var arr = navigator.userAgent.spli ...