• 通过Struts了解MVC框架,兼说如何在面试中利用Struts证明自己


        虽然目前Struts MVC框架不怎么用了,但它确是个能帮助大家很好地入门Web MVC框架,而且,一些历史项目可能还用Struts,反正技多不压身,大家如果能在面试中通过项目证明自己Struts这块也很熟,这也是个非常好的加分项。

        这里我们就从搭建Struts基本框架入手,再深入讲解些面试中常会靠到的Struts知识点,本文的文字和案例根据java web轻量级开发面试教程改编。

    ///////////////////////////////////////////////////////////////////////////////////////

    1 搭建Struts框架

    1.1 开发前端的JSP代码

        创建一个Java Web项目,名为strutsDemo,在其中的WebRoot目录下,创建前端的JSP代码calSum.jsp。    

     1 1    <%@ page language="java" pageEncoding="GBK" %>
     2 2    <%@ taglib prefix="s" uri="/struts-tags"%>
     3 3    <html>
     4 4    <head>
     5 5    <title>输入操作数</title>
     6 6    </head>
     7 7    <body>
     8 8    求和<br/>
     9 9    <s:form action="mystruts/calSum" >
    10 10    <s:textfield name="num1" label="数1"/>
    11 11    <s:textfield name="num2"  label="数2" />
    12 12    <s:submit value="求和" />
    13 13    </s:form>
    14 14    </body>
    15 15    </html>

        这个页面的效果下图所示。

     

        在第2行里引入了Struts的标签,前缀是s,所以可以用s:form和s:textfield来定义form和文本框。

        在第9行到第13行的form里,定义了两个输入框和一个提交按钮。当用户输入两个数字后,单击“求和”按钮后,本页面将根据定义在第9行的定义,跳转到mystruts/calSum.action。

    1.2 在web.xml里声明使用Struts

        如果要使用基于Struts的MVC,则必须要在web.xml里声明,否则系统服务器是不会知道在项目里用到了基于Struts的MVC处理器。web.xml的代码如下。

    1    <?xml version="1.0" encoding="UTF-8"?>
    2    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        version="2.5">
    3    <filter>
    4    <filter-name>struts2</filter-name>
    5    <filter-class>
    6            org.apache.struts2.dispatcher.FilterDispatcher            
    7    </filter-class>
    8    </filter>
    9    <filter-mapping>
    10    <filter-name>struts2</filter-name>
    11    <url-pattern>/*</url-pattern>
    12    </filter-mapping>
    13    </web-app>

        从第2行到第13行之间的web-app元素里,我们声明了两件事:

        (1)通过第11行的url-pattern,说明/*,也就是任何请求,都将由名为struts2的过滤器来处理。

        (2)在第3行到第8行之间,指定了struts2这个过滤器它的后台处理类。

    综合上述两点可知,本项目的任何请求,都将由Struts的后台处理类来处理。     

    1.3 配置struts.xml文件 

        在calSum.jsp里指定了form跳转的目的地。

        <s:form action="mystruts/calSum" >

        那么这个目的地究竟是哪里?一起来看一下struts.xml这个配置文件。    

    1    <?xml version="1.0" encoding="UTF-8" ?>
    2    <!DOCTYPE struts PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration2.0//EN"
          "http://struts.apache.org/dtds/struts-2.0.dtd">
    3    <struts>
    4    <package name="struts2" namespace="/mystruts"
    5       extends="struts-default">
    6    <action name="calSum" class="action.myAction">
    7    <result name="Positive">/positive.jsp</result>
    8    <result name="Negative">/negative.jsp</result>
    9    </action>
    10    </package>
    11    </struts>   

        在第4和第5行里,能看到名为calSum的action处于/mystruts这个命名空间里,它所对应的是action.myAction这个处理类。也就是说,calSum.jsp的请求最终是由action.myAction接收和处理。

    1.4 开发Action类

         随后开发myAction.java,它是放在action这个package下的。    

    1	package action;
    2	import com.opensymphony.xwork2.ActionSupport;
    3	public class myAction extends ActionSupport
    4	{
    5	    private int num1;
    6	    private int num2;
    7	
    8	    public String execute() throws Exception
    9	    {
    10		// 如果和大于等于0,则跳到positive.jsp页面
    11		if (getSum() >= 0)  
    12	        {
    13	            return "Positive";
    14	        }
    15		//否则跳到negative.jsp页面
    16	        else  
    17	        {
    18	            return "Negative";
    19	        }
    20	    }   
    21	    public int getNum1() {
    22			return num1;
    23		}
    24		public void setNum1(int num1) {
    25			this.num1 = num1;
    26		}
    27		public int getNum2() {
    28			return num2;
    29		}
    30		public void setNum2(int num2) {
    31			this.num2 = num2;
    32		}
    33		public int getSum()
    34	    {
    35	        return num1 + num2;  // 计算两个整数的代码数和
    36	    }
    37	}
    

        作为一个Struts的Action,本类继承了ActionSupport类。当一个请求最终到达本Action时,如果没有额外的配置,就会如同本类一样,由execute方法来处理请求。

        在第8行的execute方法里可能看到,如果两个数的和大于0,则返回Positive字符串,反之则返回Negative。这两个返回是和struts.xml里的配置相对应的。

        在struts.xml的第6行和第7行里,看到有如下的配置。

        <result name="Positive">/positive.jsp</result>

        <result name="Negative">/negative.jsp</result>

        这说明根据不同的字符串,Struts处理容器将会跳转到两个不同的jsp里。在这个Action代码里,并没有给num1和num2赋值,这是因为它们和calSum.jsp里form中的两个输入框同名,所以会自动拿到我们输入的值。

    1.5 开发两个跳转结果页面

        上文提到过,Action的execute方法里返回的不同字符串后,Struts MVC处理器会读取struts.xml里的配置,并相应地,跳转到不同的页面。下面就来编写这两个页面的代码。先来看一下positive.jsp。   

    1	<%@ page language="java" pageEncoding="GBK"%>
    2	<%@ taglib prefix="s" uri="/struts-tags" %>
    3	<html>
    4	<head>
    5	<title>显示和</title>
    6	</head>
    7	<body>
    8	结果大于或等于0,<h1><s:property value="sum" /></h1>
    9	</body>
    10	</html>
    

         这里的关键代码是在第8行,通过一个Struts的标签,来获取在Action里名为”sum”的属性对象。在myAction.java里,定义了一个getSum的方法,所以就会自动生成一个sum的属性。结果是两个操作数之和。

        Negative.jsp代码和positive.jsp很相似。唯一的差别在第8行,这里的叙述文字是“结果小于0”。   

    1	<%@ page language="java" pageEncoding="GBK"%>
    2	<%@ taglib prefix="s" uri="/struts-tags" %>
    3	<html>
    4	<head>
    5	<title>显示和</title>
    6	</head>
    7	<body>
    8	结果小于0,<h1><s:property value="sum" /></h1>
    9	</body>
    10	</html>
    

    2 通过运行,了解Struts的工作流程

       现在来总结一下整个程序的运行和跳转流程。

        第一,打开Tomcat服务器,并在浏览器里输入http://localhost:8080/strutsDemo/calSum.jsp,能看到如下图所示的页面

       

        当输入两个数字,并单击“求和”按钮后,根据如下form里的定义,会跳转到mystruts/calSum里。

        <s:form action="mystruts/calSum" >    

        第二,根据web.xml的定义,可知这个跳转请求将由struts来处理。再根据struts.xml的定义,得知这个请求最终将由myAction.java来处理。

        <action name="calSum" class="action.myAction">

            <result name="Positive">/positive.jsp</result>

           <result name="Negative">/negative.jsp</result>

        </action>

        第三,在myAction.java的execute方法里,根据最终sum的值,分别返回两个不同的字符串,从上文struts.xml片段的第3行和第4行得知,根据两个不同的返回值,会跳转到两个不同的页面里。

    3 和JSP+Servlet+JavaBean框架的比较

        在一个项目里,我们应更关注“业务该怎么处理”这个问题,而不应把大多数精力放在调试JSP到Servlet之类的跳转上。

        Struts给我们提供了一套跳转机制,我们可以简单地通过编写struts.xml和web.xml,就能比较省心地实现从前端JSP跳转到具体业务处理类的功能。而且,也只需在Action类里编写返回字符串,同时在struts.xml里编写返回字符串和跳转页面的对应关系,就能根据业务执行结果方便地跳转回前端页面。

        Struts框架是基于MVC的,它的View部分主要由JSP页面实现。Controler部分主要由Action类来承担,而Model部分主要由ActionForm组成。需要说明的是,在Struts2.0以上的版本里,开发者不需要额外定义ActionForm,由用户在前端Form里传入的数据将被自动封装成ActionFrom对象,并被最终转发给Action。

        通过下表对比一下Struts和前文提到的JSP+Servlet+JavaBean框架,综合各项对比的指标,Struts略优于JSP+Servlet+JavaBean框架。

    比较项

    Struts

    JSP+Servlet+JavaBean

    结论

    如何在后端接收前端传来的参数

    参数组装成ActionForm,并自动发送到Action里

    需要在Servlet里编写接收参数的代码

    Struts比较省心

    如何把前端的请求发送到合适的处理页面

    可以在struts.xml里统一定义请求和处理类的对应关系

    可以在web.xml里统一定义请求和处理类的对应关系

    基本持平

    后端处理请求的方式

    定义在Action里

    大多定义在Servlet类的doPost或doGet方法里

    基本持平

    如何把后端的处理结果再回传到前端

    可以在struts.xml里统一地定义处理结果和返回页面的对应关系

    需要在Servlet里手动地跳转

    Struts略优

    项目的开发方式

    程序员的工作量比较少,在必要的地方(比如Action类和Struts.xml)里填写必要的代码即可,Struts处理器能方便地实现MVC之间的跳转

    程序员可能得操心必要的细节,比如Servlet里如何接收参数,如何跳转到前端,等等

    Struts的开发流程比较省心

    4 对Struts框架的进一步了解

        Struts作为一个基于MVC的框架,能很好地处理跳转业务,能让程序员把精力更多地集中到业务开发上,通过它,程序员能很好地了解框架编程的思路和一般方法。

        不过任何框架都不是十全十美的,当你比较熟悉Struts框架后,一定能感受到它在项目开发里的一些缺陷。对于Struts的局限性,不同的人有不同的观点。但是请大家记住,在面试时,当你结合你的项目自信地说出Struts框架的局限时,即使面试官和你的观点不一致,他也一定会认为你对Struts有足够的认识。这里罗列出一些局限性供大家参考,如表所示。

    局限性

    结合项目说明

    为每个请求创建一个Action

    Struts2里,会为每个http请求实例化一个Action 对象,这对处理高并发会有些难度

    对Action 执行前和后的处理支持不大好

    比如每次进到Action前我们需要打印内存使用量,执行后需要记录跳转目标URL,这个当然可以直接写到Action里,但大家比较下Spring的AOP处理方式,就会发现单纯把前后处理写到Action里有什么不足

    对跳转的支持

    如果在一个Action里,根据处理结果可能会跳转到10个页面,那么代码可能会比较烦琐。而且一旦跳转目标页面出现变更,比如换了目录,那么在修改配置文件后,可能要求重新部署和重启Web服务器,无法实现轻量级修改

    安全性上的瑕疵

    我们可以通过类似方式直接执行Action里的方法:http://url:8080/proName/userLogin!list

    但事实上,该系统需要用户先登录才能开放用户列表。虽然我们可以通过定义拦截器来弥补这个缺陷,但毕竟属于额外的工作量

    属于侵入式

    在使用Struts时,需要继承struts的类,而且要编写execute方法。这样Struts框架就侵入到项目里了。比如做的是银行业务,如果哪天要把这套业务移植到其他Spring等框架项目里,可能工作量就比较大了

    5 关于Struts面试点的归纳

       Struts的地位似乎有些尴尬,一些小型(比如10个页面左右)的商业项目可能直接会用JSP+Servlet+JavaBean+DB的开发模式,一些大型基于企业级的项目往往采用Spring+MyBatis的框架。

        我们在面试初级程序员时,如果候选人没有在商业项目里用过Struts框架,这很正常,如果他在学校或者培训机构学过Struts,这或许也可以成为一个加分项。但如果我们看到某人在最近的商业项目里用过,那么就会详细问原因,为什么这个公司现在还要用Struts框架?反而有不少人,在这个问题上会弄巧成拙。我们听到的最多的合理回答是,基于某种原因,比如历史原因或者客户要求,这个项目还是得用Struts框架。

        具体到面试题,大家可以从网上找,在必要的时候,大家也可以多多益善地突击准备。我们给大家推荐回答问题的方式是“结合项目”,请大家看如下的问题点。

        第一,说明在这个项目里,都用到了Struts的哪些组件,比如拦截器或者验证器,你是怎么用的?

        第二,结合项目,说明自己做了哪些工作,比如在Action里,你怎么和业务以及数据库代码耦合?

        第三,能结合项目,告诉考官一些技术细节,比如拦截器是怎么用的,在该项目里结合一个需求,告诉考官拦截器的工作流程和开发方式。或者结合项目说明下验证器的用法。

        也就是说,任何技术都别停留在纸上,需要结合项目说明。

        第四,说明使用Struts框架给这个项目带来哪些痛点?

        第五,和Spring框架相比,你感觉各自有什么优缺点,请结合项目说明,不要空谈。

        当你学好了Spring框架后就知道该怎么说?

        第六,你的项目经常会扩展,业务实现方式也经常会变更,结合Struts框架说明一旦出现变更了你需要做哪些事?

        比如需要更改业务,你该更改哪些文件?一旦更改了代码,如何部署到服务器上?

        第七,这个项目的访问量是多少?最高的并发访问量能达到多少?Struts框架能否很好地处理高并发的情况?

        关于常用的技术问题,在本章里都已经提到,我们通过如下问题点来对本章做个总结。

        ①在Struts2里,如何实现一个Action?

        ②怎么指定进入Action后该调用哪个方法?

        ③定义验证器的步骤是什么?

        ④定义拦截器的步骤是什么?

        ⑤Struts2中的type类型有哪些?如果不写type,默认是什么?

        ⑥如何通过配置type类型,实现一个Action往另外一个Action的跳转?

        ⑦描述下Struts MVC的工作流程和开发模式。

        ⑧和JSP+Servlet+JavaBean的开发模式相比,Struts MVC有哪些好处,同时,说明下Struts框架有哪些不足。     

        

        

  • 相关阅读:
    cookie、 Session Storage 、 Local Storage
    json 常用的方法
    ssm 框架 使用ajax异步,实现登陆
    ssm框架整合,配置文件中的配置内容
    ipv4和ipv6的区别
    分析域名的解析过程
    网络体系结构总结
    线程同步和异步
    博客目录
    [STM32H743]按键控制LED
  • 原文地址:https://www.cnblogs.com/JavaArchitect/p/7759769.html
Copyright © 2020-2023  润新知