• Spring


    认识Struts2有一段时间了,用它做了几个小型web应用,发现用Struts2使得开发这些小web应用变得非常简单。这让我变得有点茫然。如果没有Struts2,如何开发web应用?开发web的本质是什么?Struts2存在的意义是什么?它究竟为我们做了什么?我们要抛开它天生的骄傲,还原它的本质。由于本人才学疏浅,以下探讨不光是我个人见解,更多的是借鉴了广大网友和相关书籍的经验之谈, 在此先谢过这些高手。

    鸣谢:《Struts2技术内幕-深入解析Struts2架构设计与实现原理》陆舟 著

     http://www.cnblogs.com/sharpxiajun/p/3936268.html (为什么做java的web开发我们会使用Struts2,spingMVC和sping这样的框架?) 作者:夏天的森林

    首先,先不要急着讨论Struts2的本质,要先弄清楚几个web开发的基础概念

    1.分层开发模式

    从宏观上说,web开发模式中最重要的一条是分层开发模式。分层开发模式是指,在开发J2EE程序时,将整个程序根据功能职责进行纵向划分。一个比较典型并为大家熟知的划分方法是将整个程序分为:表示层、业务层和持久层。

    我们所熟悉的一些著名的框架,实际上就是为了解决各个开发层次的编程问题而设计的解决方案。比如说:Struts2是表示层的框架;Spring是业务层的框架;Hibernate是持久层的框架。

    2.MVC模式

    在分层开发模式的前提下,每一个层次都可以单独研究,并寻找合适的解决方案和最佳实践。对于表示层,有一种称之为MVC的模式为广发使用,并在此基础上创建了许多这种模式的开发框架。

    其实任何一个B/S应用的本质就是“请求--响应”的处理过程的集合体,

    在这个 请求--响应 的过程中,有三大元素是必不可少的:

    1. 数据模型——Model
    2. 对外交互——View
    3. 程序的执行和控制——Control
    下面图是我根据一副流行了很多年讲述MVC模型的图制作的,帮助大家理解MVC模型:
     
     


    通过这张图可以清楚地了解到一个web应用最基础的业务流程。

     

    接下来,在探讨Struts2的工作本质之前,不妨忘记所谓的框架,先来研究下一个最基本的web应用的业务流程,用最本质的方式来实现一个简单的MVC雏形,以这种方式来思考Struts2到底为表示层解决了什么样的编程难题,难道只是实现MVC这么简单吗?

    我们知道,Servlet的作用是接收浏览器传给服务端的请求(request),并将服务端处理完的响应(response)返回给用户的浏览器,浏览器和服务端之间通过http协议进行沟通,其过程是浏览器根据用户的选择将相关信息按http协议报文的规范组装请求的http报文,报文通过网络传输到指定的服务器,服务器通过特定的web容器接收这个报文信息,例如:tomcat,jetty,jboss这样的web容器,web容器将http报文解析出来,如果是用户请求,最终解析出来的报文信息会用一个request对象存储起来,服务端使用这个request做完相应的处理后,服务端程序将结果封装到response对象里,然后将response对象交给web容器,web容器则把这个response对象转变为http协议的报文,并将报文回传给浏览器,浏览器最后解析这个相应报文,将最终结果展示给用户。

    在了解以上这些后,我们以Registration(注册)作为业务场景,我们需要一个JSP页面来呈现用户注册的各个字段、一个User类来表示用户实体以及一个RegistrationServlet类来处理注册请求。代码如下:

    registration.jsp

     

        <form action="/struts2_example/registration" method="post">  
            user name:<input type="text" name="user.name" value="hnyd" />  
            birthday:<input type="text" name="user.birthday" />  
            <input type="submit" value="submit" />  
        </form>  

    User.java

     
     1     public class User {  
     2       
     3         private String name;  
     4           
     5         private Date birthday;  
     6       
     7         public User() {  
     8               
     9         }  
    10           
    11         //  此处省略setter与getter方法  
    12           
    13     }  

    RegistrationServlet.java

        public class RegistrationServlet extends HttpServlet {  
          
            @Override  
            protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
                    throws ServletException, IOException {  
          
                <span style="color:#ff0000;">// 从request获取参数  
                String name = req.getParameter("name");  
                String birthdayString = req.getParameter("birthday");  
                  
                // 做必要的类型转化  
                Date birthday = null;  
                try {  
                    birthday = new SimpleDateFormat("yyyy-MM-dd").parse(birthdayString);  
                } catch (Exception e) {  
                    e.printStackTrace();  
                }  
                  
                // 初始化User类,并设置字段到user对象中去  
                User user = new User();  
                user.setName(name);  
                user.setBirthday(birthday);</span>  
                  
                // 调用业务逻辑代码完成注册  
                UserService userService = new UserService();  
                userService.register(user);  
                  
                <span style="color:#ff0000;">req.getRequestDispatcher("/success.jsp").forward(req, resp);</span>  
            }  
        }  

    除了上述代码外,我们还需建立起JSP页面中的form请求与Servlet类的响应之间的关系。这一关系是在web.xml中维护的,代码如下:

    web.xml

     

    1. <servlet>  
    2.     <servlet-name>Register</servlet-name>  
    3.     <servlet-class>com.example.web.RegistrationServlet</servlet-class>  
    4.   </servlet>  
    5.   <servlet-mapping>  
    6.     <servlet-name>Register</servlet-name>  
    7.     <url-pattern>/struts2_example/registration</url-pattern>  
    8.   </servlet-mapping>  

    上面是一个简单的用Servlet处理的业务,由于Http协议与Java数据形式的不匹配性,RegistrationServlet在数据类型转化和实例化对象上花费了大量的精力,我们编写了额外的代码,把页面上传来的日期值转化为Java中的Date对象。在参数的数量和Java对象越来越来复杂的情况下,这种额外的代码就会变成一种灾难,甚至成为我们开发的主要瓶颈之一。

    而Struts2通过拦截器帮助我们完美的完成了以上这些和核心业务无关的工作。

    RegistrationServlet.java的最后一行,Servlet将处理过的数据重定向至success.jsp页面,即通过硬编码的方式完成程序执行跳转的,这种方式不但无法支持多种新的视图技术(模板技术、JSON数据流等等),同时也无法使我们从复杂的视图跳转的硬编码中释放出来。

    解决这个问题的最有效的途径是把不同的视图技术进行分类,然后针对不同的视图类别封装不同的视图跳转逻辑。Struts2就是这么做的,Struts2通过配置文件来进行区分并实现不同的视图跳转。

     

    即:Struts2是一个运行于web容器的表示层框架,其核心作用是帮助我们处理Http请求

    Struts2处理Http请求(Request),并进行内部处理,再进行Http返回。 

     

    总而言之,Struts2帮我们解决了我们需要和Http打交道的众多繁琐的工作,这也是Struts2作为分层开发模式中表现层的核心所在。

  • 相关阅读:
    K8S实战(十七)| 通过 StorageClass 实现动态卷供应
    K8S实战(十六)| 持久化存储卷
    K8S实战(十五)| 存储卷概念
    K8S实战(十四)| ConfigMap 对象
    K8S实战(十三)| Secret 对象
    K8S实战(十二)| 为 Ingress 以及后端 Nginx 增加证书
    批量删除git 本地分支、远程分支、tag
    React 页面间传值的个人总结
    搭建一个属于自己的webpack config(-)
    HTTP 2 新特性
  • 原文地址:https://www.cnblogs.com/xiaonihao444/p/9008438.html
Copyright © 2020-2023  润新知