开发者学堂课程【高校精品课-上海交通大学 -互联网应用开发技术:MVC1】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/76/detail/15766
MVC1
Struts
1. Struts 2
starts是一个实现了MVC架构的一个东西。
也支持REST,AJAX,JSON这样的东西。在struts里面。就想支持MVC的架构,所以来看看如何支持。
首先struck里面。要注意的一点是Struts框架一旦使用,所有的请求都被叫dispatcher filter的这样一个filter给拦截掉了、filter市场,之前讲servlet的时候,filter其实就是这个东西。servlet的filter,也就是filter的作用是会监听一些请求,但是不会做处理,然后往回发,是在里面加东西。
当时讲servlet的时候,在filter里面是对加了一个属性,比如人现在困,还是很兴奋,还是饿了,然后请求会继续发,也就是比如对time超链接是有一个servlet在进行拦截,在处理里面的内容,但是可以在前面有一个filter,也在监听链接,会对请求做一些处理,做完处理之后,还是最终会给servlet处理。而且filter,可以不止一个,看到一个请求来了,可能穿过一个filter,穿过第二个filter,最终才到达servlet进行处理。这是之前讲的filter,那么struts的框架。
要完全接管前排所有的东西,所以会用filter去接管所有的请求。那接管怎么接管的。然后过来之后,也有一些像filter一样的东西,不叫filter,包装了以后,起个名字叫interceptors, interceptors叫拦截器,但的拦截器本身不会做很复杂的逻辑操作,而且关键是不会往请求里面写的东西。
跟filter的作用是一样,最终是要把请求调给真正处理链接的一个对象去处理,对象,就不叫servlet的,包装一个叫action,所有的action都有一个execute的方法,那么,都有一些set X X或者get X X的方法,有一个命令的模式叫做command,其实就是command类型的。反正就是有一个execute,execute会去执行对前排的一个处理,然后处理完之后,里头会有很多属性,所谓的set X X或者get X X就是在获取或者是设置这些属性,这些属性就是处理完前排的逻辑之后。得到一个结果,就设计到自己里面。然后controller,除了把请求调度给后台的model去执行之外,还去调用前端的某一个页面。
会请求来了,就把页面呈现给用户。然后页面,就可以通过get X X去拿到action里面这些属性当中某一个就能拿到了处理的结果,那在设置里面就可以看到。dispatcher filter就起到了controller的作用。model就是在实现具体的业务逻辑,这是真正让客户看到的view页面。页面去抓哪一个model的内容,是靠这一边的的dispatcher filter来决定。怎么决定的,所以需要一些page文件去描述事情。也就是希望打破俩之间的耦合关系,一个页面没有一定要从哪个action去拿属性,拿处理的结果,俩的关系应该打破,完全靠这一边去动作,让之间建立关联,Struts2是的一些特性
总的来就是是一个MVC架构。
2.Core Components
里面的一些重要东西,第一个是action,要去实现业务逻辑,然后interceptors是在实现这种页面的前排的请求往后观的一个转发,以及页面到底是呈现哪个页面这样的逻辑,整个这一块儿相当于controller,那么还有一个Value stack,可能不太会用到,就是在复杂的系统里面,如果一些不同需要根据其构件集中处理才会用到,那在这里面可能不太会用。Result types 就是action执行完之后,执行完的结果是什么。
是成功还是失败了,结果本身是调度页面的一个依据,真正的result,那就是在这里面这些属性是怎么拿出来以后由view去呈现,主要是这几个概念。
虽然不需要硬编码,但是需要page文件里写,有三个主要的page文件。
Struck.xml和struck.properties是struck相关的,是web.xml的,大家在开发web应用的时候,其实已经看到文件。原因是因为其实现在如果大家用springboot,可能基本上不用去管,但是用struts的时候还必须要用一下,里面要写点东西。另外还有一个Struck.xml是在page,比如执行了execute之后就成功了,应该看在页面迁移到哪个页面上。给用户展现的一个界面,如果失败了,应该展示哪个界面。
然后struck本身有一些配置,但是在如果目前初学的话,要知道这里头其实没有什么特别的,但至少在目前这节课没有讲到后面讲到spring。还要支持跨域的时候。在这里面有一些法,需要page一下,到那时候再,那现在可以忽略了,那这节课主要是看看怎么通过这两个文件来实现刚才的MVC的结果。
<welcome.file-list>
<welcome-file>index.jsp</Wacome-file>
</welcome-file-list>
<filter>
<filter-name>Struts2</filter-name>
<filter-class>
org.apache.Struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>Struts2</filter-name>
<ur-pattem> /*</ur-pattem>
</filter-mapping>
web APP的应用。需要有一些什么样的一些配置信息,比如的应用启动之后,觉得的页面的首页是谁。就是welcome file。那可以配置一下,如果不去特别的指定,可以看到用工具帮生成的工程的模板,里面就是写法,首页就是index.jsp当然讲JSP,因为现在大家认为这是个过时的基础。但是在这地方,就要借用一下,因为前端不都是web的,先借用一下JSP来用一下看主要是看后端怎么跑起来,然后所有的struck的应用,必须要写的,而且只能写成样子,在什么。在整个应用需要有一个Struts2这样一个filter。filter,就是要去做dispatch,就是接管请求,让去做分发,去按照struts的XML文件里的内容去做分发。
那到底哪一些需要接管分发。一个struts的应用里面,当然是所有的请求全部要被接管,所以就写在任何一个。Struts的应用,的web xml写法都是这样。唯一变化可能是这。但底下这两个是不变的,所有的请求全部被Struts2接管。然后来看看structs2描述什么。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation
//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.devMode" value="true"/><package name="basicstruts2" extends="struts-default"><action name="index">
<result>/index.jsp</result>
</action>
</package>
</struts>
上面一个片段就是大概会。的应用包是什么,然后的发展是什么。至于含义。那么有解释,但是不用去管,反正大概是先这样写,讲到后面,需不需要跨越,那其实里面重要的部分是这些。
就是要去写的系统里头有多少个action,每个action如果有返回结果,默认值是Success,没有写着Success正常返回,应该跳到哪个页面去。就是配置这样一些信息,每一个action返回的结果的不同,应该怎么去跳出来。那这有什么含义。就这样做有什么意义,的意义就是在代码里是不用去管处理完应该跳到哪个页面,什么意思,
servlet的全部是怎么写的。是在那个process也就是do get方法里头,写的什么。要获取Response上面的writer,要在里面。去写进去,的响应是什么。那这样写是不是等于写死了。当前servlet,的返回的页面就是页面不能改,把返回跳到哪个页面这件事,想和servlet的结果解开。就像这里看到了,如果处理正常结果。跳到页面,如果是异常,跳到另外一个页面,但是不管跳哪个页面,在代码里不写死。通过配置文件来配,就是想要做的事情,一旦这样做,是不是will和这里面的代码就实现了。这种想实现的目的。
3.Actions
整个struct里面,看到的全是action。Action里面只有一个方法是必须要写的,就是execute执行,在执行的时候,总要返回一个值。然后一直可以去成功或者是error。还有几个默认的值,那么在配置这上面是代码,在配置文件就在那个struct. xml里面,要这样,有一个action,action对应的类就是,这个类名就和的类名对应,导致包名和工程的包对应。这个类有一个返回值。的返回值入不去明确指定是什么,一般就是Success,所以单一结果的时候就跳到view.jsp。那现在大家就会看到action,就没有应该跳到哪个页面,只返回值是成功和失败,具体跳到哪个页面里,在struts.xml。这就比较灵活,那如果返回值不止一个,
class MyAction{
public void String execute() throws Exception{
if( myLogicWorked()) {
return "success";
}else{
return "error";
}
}
}
<actionname="my"class="com.fdar.infoq.MyAction">
<result>view.jsp</result>
<result name="error">error.jsp</result>
</action>
比如有success,有error,在底下配置的时候就会。默认的结果就是success会跳到view.jsp,如果返回的类型是error,应该跳到一个叫error.jsp页面上去。那这有什么处。这是Java的代码。这是XML文件。觉得改Java代码容易还是改XML文件容易。因为有idea,这个代码已经拿到了,然后别人已经写了,已经给了代码可能不能改,人家只给了一个.class,编译出来的.class,甚至是给了把整个工程编译的.java文件。就没源码,无法修改。但是XML不一样,不存在编译问题,就是文本文件打开来就改了,从意义上来,改比较简单,只要改源码就涉及到要重新编译。没有编译器。然后重新编辑完了,还得要重新部署,一般来,改完代码重新编译的话,有可能会报错,有一系列的事情,如果是改XML,至少代码不用动,而且肯定能通过编译,这些都不用改,、随便拿个文本编译器打开改。比如认为error不要跳到error.jsp。页面太难看了,写了一个叫做beautiful error.jsp页面,只要改 error文件就能实现的功能。不需要改任何源码。就所谓的action和页面跳转的逻辑,的意思就在这儿。代码本身并没有去写一定要跳到哪个页面。只了处理的结果是正确还是失败,真正跳转的逻辑是struts接管以后读配置文件来的,配置文件是写的,可以根据自己的需求去写。所以就比较灵活。
4.Interceptors
前端可能会有一些拦截器。写一个action,也可以写一个拦截器。拦截器的目的就是对所有的请求做一些处理,然后返回一些结果。一旦定义拦截器。可以在action里面。前面就有一个拦截器,帮做一些事情,所以可以定义一些拦截器在action后面,可以去复用这些拦截器。在action里面直接清楚,要要去引用action,就是凡到action进行处理之前,必须经由先做一下预处理。
<interceptor-stack name="basicStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="servlet-config"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="params"/>
<interceptor-ref name="conversionError"/>
</interceptor-stack>
<action name="my" class="com.fdar.infoq.MyAction">
<result>view.jsp</result>
<interceptor-ref name="basicStack"/>
</action>
那么拦截器本身可以像看到的servlet里面的filter上构成一个链,叫一个栈。把这些若干拦截器构成了一个栈,意味着一个请求过来,如果选择用basisstack。那就意味着当一个请求能够真正到达MyAction,action执行之前。是经历了这一系列的nterceptor-stack。每一个可能都在这里面,在请求里面做了一些预处理,最后到达这里的时候。那就可以来实现的逻辑了。那这种拦截器总的来适用于什么,就是后台有很多action。有一些公共的活儿要干,把这些就放到一个intercept里头。然后把配到的前面去。这样的话,这部分重复的代码就不需要在action里面去写。通过interceptor就可以实现代码的复用,所以本质上来也就是一个代码的复用,和在讲servlet里面的filter的概念是一样。如果filter只对这一个servlet的起作用,那的意义就不大了,一定是对若干个servlet都起作用,再复用这份代码,所以把放到前面去。所以仔细想想道理,就知道为什么会有filte。或者一个servlet这样的东西出现。interceptor里面,也只有一个需要必须实现的方法,就是intercept,就是当一个请求来了之后,包装成了一个叫做Actioninvacation的东西,怎么从对进行操作。
5. Return Types
然后返回类型,就是刚才的,会返回success或者error,如果觉得这些都不行,也可以自定义一下类型。、然后自定义之后,在其的action里面就可以去引用这种类型。那类型有什么意义,其实这类型没什么,就像一个标记一样。认为就是个枚举类型都可以。反正是根据类型来决定页面跳到哪里去了。这是最核心的一些功能。拿一个例子把全串起来写Hello World。
6. Hello World Using Struts 2
尽管例子非常简单,但是在后面要慢一点,变得越来越复杂,越复杂就可以看到的一个全貌。在hello word里面。用MVC模式的话,第一个要写M是什么,就是业务逻辑。就是如果前台的hello world是从一个。后台的比如数据库里拿的或者什么里面,反正是数据应该是从一个model里拿出来。那就应该存储着欢迎的消息。有一个去显示这条消息的东西,那就是view。要还有一个就是要去拦截前台的请求。去调用后面的model。然后让view去到model里面拿内容的这样的东西,就是controller,也来控制用户和model以及view之间的交互。然后交互,也没那么智能,需要读struts.xml来实现,就要去把已经解耦的action 和 view给耦合起来做这样的事情。首先model怎么写。
public class message store {
private String message;
public message store(){
setMessage(“Hello Struts User");
}
public String getMessage () {return message;}
public void setMessage(String message) {this.message = message;}
public String toString(){
return message + " (from toString)";
}
}
Model就是要执行业务逻辑,按照的业务逻辑,做一个最简单操作。就是存了一个字符串,字符串是在初始化的时候设置的。Hello Struts User。可以从数据库里拿出来,那只是后台的,再后面的逻辑跟前面没关系。反正不管怎么样。在维护message,这是最重要,然后message,可以get可以set,set就是在构造器初始化的时候,传递进来了的消息。get就是可以对别人调用。另外有一个 toString的方法,就是把message。写了一个这样的字符串返回。这就是那个model。
再来看action,
public class Hello WorldAction extends ActionSupport{
private message store message store;
public String execute()throws Exception {
message store = new message store();
return SUCCESS;
}
public message store getmessage store(){
return message store;
}
public void setmessage store(message store message store){
this.message store = message store;
}
}
在struts里面所有的action都实现扩展 ActionSupport类的一个子类。Action里面就会去持有一个message store的类型的一个对象。然后对象,action只有一个execute。execute创建一个新的message store对象赋给变量。这样就不会是null。关键返回一个success。然后的变量本身有get和set方法。结束就是action。
看前端的脚本,
<%@pagelanguage="java"contentType="text/html;charset=ISO-8859-1"pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
前端的脚本里面。了要借用一下。然后有一些是从Struts的标签库里取出来,凡是这种标签库的前缀是S,就是看到的这种S开头的这种标签是struts,页面的title是hello world,就在窗口的上面。标题栏显示内容,的真正内容是已经过hello多少次了。那么多中间值从哪儿来的,用的是struts的一张property的一个标签,的值就是hellocount。然后再以H2的方式显示一个叫做message store. message的信息出来,那上面这一行先不看,就看这一行。要从一个叫message store对象里去读message。那么现在问题就来了,在页面里面哪里也没出现一个message store。怎么能去抓到message store的message方法的属性。这件事儿怎么来的,在前面还要做一个设置
<?Xml version=“1.0"encding=
”
UTF-8
”
?>
<IDOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<constant name="struts.devMode" va ue="true"/
<package name="basicstruts2" exteitds="struts-default"
<action name="index"
<result>/index.jsp</result>
</action>
<actionname="hello"class="org.reins.mvc.struts.sample.action.Hello WorldAction"method="execute">
<result name="success"/Hello World.jsp</result>
</action>
</package
</struts>
就是struts设置。页面上来之后,如果访问index。就应该直接跳到页面上。Index不是一个新的action,就是在URL里面输入index,应该跳到页面上。所以的意思就是,这就是主页。在系统里有一个叫hello的action,就是刚才写的action ,Hello WorldAction。在运行的时候,在监听路径。只要路径前端页面里产生了这样一个URL请求,到了后台就被类处理,被哪一个方法,被execute的方法处理。execute的方法干什么,创建了一个message store类型给自己的。让返回success。关键就在返回结果是success,跳到Hello World.jsp去。那就到了Hello World.jsp页面。然后页面就不管从哪儿来的,反正只要跳过来,继续那个action里面的属性。那看还是从Hello WorldAction来了,Hello world action类确实有message store的属性。怎么实现解耦。
写一个Hello struts action跟刚才的页面是是一模一样,里面也有一个叫message store。但是如果在这里。如果改变一下,hello请求不是由Hello WorldAction来处理。是由Hello struts action来处理。同样,的success之后还要跳到Hello World.jsp。那么就可以看到Hello World.jsp页面,根本就没有意识到到底是。Hello world action还是Hello struts action,反正是有一个action过来的,就抓action里面message store。所以是不是页面view和后面model是实际上是解耦的,只要有message stop对象,管从哪儿来的,就可以去调用,所以回想一下。看这是那个页面,根本就不知道后面action是谁,可以是hello word。也可以是Hello struts。到底是哪个取决于这一点,去读了那个struts.xml,来决定。那不管是从哪个action跳过来,反正上面只要有那个message store就能调用。所以view和model是解耦的。
首先model没有一定要跳到那个页面,其实页面没有一定要抓哪个action的message store。至于怎么跳转,用controller来根据配置文件调整。这就是的精髓了。看到了这样一个效果。所以这里面没有去一定要从action出来,那反正只要有对象就能抓看到的步骤。那么在web.xml里面的首页,然后用strusts来拦截所有请求。整个业务就会跑,于是跑起来的话,就会出这样的效果。
因为把其的功能都写在页面。稍微改写一下,跟刚才内容可能不太一样,就是。
写了个welcome to struts2,然后有个超链接,超链接会激发action,就到hello ,然后超链接上写的内容是hello word,一旦激发那个请求到hello ,来看后台action。
就会实现action support类。然后有一个message store。先不看其的,就先看message store的,然后的执行就是创建了message store,然后返回success。
hello就是由刚才的类来处理的,的返回如果是success,就要跳转到叫hello word.jsp页面。这个hello word.jsp页面如下
主要中间这行,就会把这message store的message取出来。所以跑一遍这个例子的话。就是看这个。
第一个。这个链接就是刚才讲的hello world。就抓到了Hello struts user就是在这个message store里面。就在这个message store里面存储的一个消息,hello strut。
那这个例子里面就是的这个结构里面最重要的是。在Hello World.jsp里面没有一定从后面哪个action抓住,而前面的action也没有一定要跳转到哪个页面去。这个逻辑完全是在struts.xml里面来控制。然后整个所有的系统里面的。所有的请求全部被struts接管。在xml上算出来结果。至于这个message store,在这个action里持有的,就像刚才的action 和view是没有反映大家的解耦解开,那也就是的重要地方在于这个配置文件。如果换一个action,只要有message store。
这个整个系统仍然可以跑,里面没有这个绑定,真正的绑定是在这个配置文件里面写的,那如果想换个绑定方式。所以没有定编码,通过xml的方式来实现,的效率就会提高。这个例子能直接让看到,就所谓的M和V的解耦是靠C来过,c本身没那么聪明,是靠这个配置文件,配置文件就是在去写的,所以体现了的意志。现在M和V解耦之后就会看到的代码考虑过就提高了,想换一种页面迁移的方式就变得非常简单。把这个事情稍微变复杂一点,
<%@taglib prefix="s" uri="/struts-tags"%>
<body>
<h1>Welcome To Struts 2!</h1>
<p>
<a href="<s:url action='hello'/>"Hello World </a>
<s;url action="hello" var="helloLink'>
<s: param name="userName">Bruce Phillips</s:param>
</s:url>
<p>
<a href="S(helloLink]">Hello Bruce Phillips</a>
</p >
<p >Get your own personal hello by filling out and submitting this form.</p >
<s:form action="hello">
<s:textfield name="userName" label="Your name" />
<s:submit value="Submit" />
</s:form>
</body>
除了刚才看到这个链接之外,再给加一个。加一个是到Hello 的这个链接,然后会带一个参数username 。
username就是这个Bruce Phillips。就想做这个信息进去,然后这个action。对应的是谁有没有超链接。然后对应的这个超链接就是这个在这里定义的,所以会对这个还要把带一个参数进去。然后在这里面可以看到。
在底下有一个就是比更进一步的是,有一个input一样东西,让用户填用户名。填了这个用户名之后,就是不是写死的用户名字,不能为这个Bruce Phillips。让用户写用户名。然后submit的时候,也对这个Hello 这个位置发一个请求出去。请求出去之后,会把这个username带进去。那不管怎么样,现在出现了一个在hello这个地方带参数。这个参数,在第二种情况里面是写死的。
第三种情况,就是用户填进去。不管怎么样,带了一个username这样的参数过去。就是这样,第二种在这里写死了。
这个链接看看这写死username是什么,第三个是在这里填进去的内容,填了以后再做,这两种,可以看成是一样的,就是要去看后面的hello,这个action怎么传参数。这个前端和后端怎么传参数。那么怎么传参数,有两种解决方案。就是怎么在后头拿到这个参数。
HelloWorld.java(Solution 1)
public class HelloWorldAction extends ActionSupport {
private String userName;
public String execute() throws Exception{
messageStore = new MessageStore();
if (userName != null) {
messageStore.setMessage(messageStore.getMessage() + “” + userName);}
return SUCCESS;
}
public String lserhan () { return userName;}
public void setU ea (String userName){
this,userName = userName;
}
}
第一种Action直接定义一个叫userName的属性。 execute之后直接就判断userName是不是为空。如果不为空,说明从前端拿到了这个参数,就直接从后端显示的内容就是messageStore里的消息,这里面的消息就是hello struts user,然后再加个空格,再加上这个user name,返回给前端还是success。那这是第一种方法,看起来比较自然,就是加一个属性,自动就会赋值,只要这个名字和参数的名字完全一致,就可以匹配上,自动给赋值。对象要有get和set方法,否则赋值不进来。
HelloWorld.java(Solution 2)
public class HelloWorldAction extends ActionSupport {
public Stringhacut () throws Exception {
messageStore = new MessageStore();
ActionContext context = ActionContext.getContext();
Map params = context.getParameters();
String[] users = (String[]) params.get("userName");
if (userName != null){
messageStore.setMessage(messageStore.getMessage()+ “"+userName);}
return SUCCESS;
}
}
第二种方法是没有设计这样的一个userName的一个属性,没这样做,而是一个action进来之后,Action有一个上下文对象。获取上下文对象的,上下文对象里面就能获取所有的参数。在一个map里。 map的键。就是参数的值,就是的值。那这样得到了,也可以得到那个userName。得到userName这个参数之后,要注意的是。还得判断是不是为空。
所以这部分跟上面这部分是一样的,区别就是上面是定义一个属性,这个属性名和前面的这个匹配一下。后面这个是根本就不定义一个属性,不要用get的方法去处理。
那两种方案都可以,但至少在一件事情。就是前端和后端是如何传递参数,前端如何把参数传到后端,在struct这种框架下怎么传过来。那拿到这个属性之后,剩下的事情就是的业务逻辑。想怎么处理就怎么处理。所以跑的话,就看到俩不一样,那可以在里面可以看到这个效果。随便写一个用户名,比如李小龙。那么点击一下,就看到Hello struts user Bruce Lee。
就会这样的东西。
7. Coding Struts 2 Actions
那么这是看到的前端和后端总成参数。然后再看一下,如果传递这个参数比较复杂的,比如再增加一个功能,就是让用户去注册。
怎么注册就是点击超链接跳到这个页面。
<?xml version="1.0 encoding="UTF-8"?>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%>
<body>
<h3>Register for a prize by completing this form.</h3>
<s:form action="register">
<s:textfield name="personBean.firstName"label="First name">
<s:textfieldname="personBean.lastName"label="Lastname"/>
<s:textfield name="personBean.email" label="Email"/>
<s:textfield name="personBean.age" label="Age"/>
<s:submit/>
</s:form>
</body>
<s:head>
</html>
这个页面里面,就包含了若干个输入域,然后要输入first name ,last name email配置等等,然后有一个submit按钮去提交。那么这些值会放到哪里去,会放到一个personBean的这几个属性,那这个personBean在哪里。看到刚刚那个please register点完之后跳到这个页面,
写了一些东西,Submit之后,这个值会付给一个叫personBean的对象,这些东西要怎么赋值,就是要写一个后端的一个Register这样的一个action,里面有一个叫user的属性,的名字叫personBean。然后执行的逻辑,底下就自己写了一个到habit,就是用personBean里头的东西取出来以后,把存到数据库里。这个动作会返回一个success。有这个personBean,所以有增加就是get和set。因为在这里只是看到跳到这个页面,然后会发出一个register的请求。
对这个register发了请求过去,所以才能够去访问到register和这个类。这个action在里面的这个属性,这个personBean。但是现在还有一个问题。只是对这个位置就发一个请求处理。还没那个请求是不是在监听,所以要在spring的struts的这个配置文件里面写清楚,对着这个位置发的请求就要由这个类去处理,这样大家才关联起来。那么也就是前面这儿发出来的请求被struts拦截,Struts在Struts .xml里面去拿,实际上是要到这个action里面去执行,去掉excute方法,所以就回到了这个register里面,就发现里面有personBean。于是就把前面要求这个页面上要求会对personBean赋值的这些信息都付给了这个personBean。现在就把前后台串起来,那跟刚才同样的道理。
这个页面只后台处理,的action应该有个personBean的属性,一定要去register action是在XML文件里面去配了,那同样道理,如果不是,换一个,比如用new register,里面也有一个personBean的话,那这个代码也是不用改了。也就是前台的页面和后台的这个action之间没有任何耦合,完全就是靠这个struts把关联起来,所以这就是这个代码的处。然后前端这里。在处理的时候,会返回这个success,在这里如果是success就跳到这个页面。如果是返回的是input,就让还在当前的页面。那怎么会有input,那这里用到的这个user这个类就是之前反反复复出现类似的user的类都没有做任何修改直接拿来用。那么thank you这个页面在干什么。
thankyou.jsp
<html xmlns= http://www.w3.org/1999/xhtml>
<body>
<h3> Thank you for registering for a prize.</h3>
<p>
Your registration information:
<s property value="personBean" />
</p>
<p>
<a href- <s:url action='index' />' Return to home page</a>
</p>
</body>
</html>
thank you是从register跳过来,而register里面是有那个personBean,所以把这personBean的值拿出来显示一下,这是的注册信息,然后有一个return to homepage的东西,回到ID,这个index在前面也过,index会跳,index打GSP上去。这种看到的页面,看到的效果和注册。其实注册的时候做了这样一个拦截器在做验证的动作。
Submit就写到后台去了。
大家要看到的是整个这个操作的过程里面,写的代码里。无论是这些页面还是这些action,互相之间都没有直接引用,所以就解耦了。
这就是MVC框架,解耦最大的好处就体现在通过struts的XML把大家组织在一起,如果未来想替换这种处理的逻辑。那么只要去改struts.XML就可以,其内容一概不动。
所以代码可维护性非常大。就看到这个效果在往后的还有像像这个挥发的状态等等这些维护。