java 自己写mvc框架_设计自己的MVC框架

取这样一个标题太大,吸引眼球嘛@_@。

事实是最近读《J2EE设计模式》讲述表达层模式的那几章,书中有一个前端控制器+command模式的workflow例子,就琢磨着可以很简单地扩展成一个MVC框架。花了一个下午改写了下,对书中所述的理解更为深入。我想这也许对于学习和理解设计模式,以及初次接触struts等MVC框架的人可能有点帮助。因为整个模型类似于struts,我把它取名叫strutslet^_^

(一)完整的类图如下:

4e3b2d8e07a2fd7915fe94464a743205.png

1。前端控制器(FrontController):前端控制器提供了一个统一的位置来封装公共请求处理,它的任务相当简单,执行公共的任务,然后把请求转交给相应的控制器。在strutslet中,前端控制器主要作用也在于此,它初始化并解析配置文件,接受每个请求,并简单地把请求委托给调度器(Dispatcher),由调度器执行相应的动作(Action)。调度器把action返回的url返回给FrontController, FrontController负责转发。

2。Action接口:command模式很好的例子,它是一个命令接口,每一个实现了此接口的action都封装了某一个请求:新增一条数据记录并更新model,或者把某个文件写入磁盘。命令解耦了发送者和接受者之间联系。发送者调用一个操作,接受者接受请求执行相应的动作,因为使用Command模式解耦,发送者无需知道接受者任何接口。

3。Dispatcher:调度器,负责流程的转发,负责调用action去执行业务逻辑。由调度器选择页面和action,它去除了应用行为和前端控制器间的耦合。调度器服务于前端控制器,它把model的更新委托给action,又提供页面选择给FrontController

4。ActionForward:封装了转向操作所需要信息的一个模型,包括name和转向url

5。ActionModel:解析配置文件后,将每一个Action封装成一个ActionModel对象,所有ActionModel构成一个map,并存储在ServletContext中,供整个框架使用。

(二)源代码分析:

1。Action接口,只有一个execute方法,任何一个action都只要实现此接口,并实现相应的业务逻辑,最后返回一个ActionForward,提供给Dispacher调用。

4f1150b881333f12a311ae9ef34da474.png

package

com.strutslet.core;

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

import

javax.servlet.ServletContext;

4f1150b881333f12a311ae9ef34da474.png

import

javax.servlet.http.HttpServletRequest;

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

import

com.strutslet.model.ActionForward;

4f1150b881333f12a311ae9ef34da474.png

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

/** */

/**

d18c02628675d0a2c816449d98bda930.png * command接口

d18c02628675d0a2c816449d98bda930.png *

@author

dennis

d18c02628675d0a2c816449d98bda930.png *

8f1ba5b45633e9678d1db480c16cae3f.png

*/

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

public

interface

Action

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png

public

ActionForward execute(HttpServletRequest request,ServletContext context);

8f1ba5b45633e9678d1db480c16cae3f.png}

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

比如,我们要实现一个登陆系统,LoginAction验证用户名和密码,如果正确,返回success页面,如果登陆失败,返回fail页面:

4f1150b881333f12a311ae9ef34da474.png

package

com.strutslet.demo;

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

import

javax.servlet.ServletContext;

4f1150b881333f12a311ae9ef34da474.png

import

javax.servlet.http.HttpServletRequest;

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

import

com.strutslet.core.Action;

4f1150b881333f12a311ae9ef34da474.png

import

com.strutslet.model.ActionForward;

4f1150b881333f12a311ae9ef34da474.png

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

public

class

LoginAction

implements

Action

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png

private

String name

=

""

;

d18c02628675d0a2c816449d98bda930.png

public

ActionForward execute(HttpServletRequest request,

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif   ServletContext context)

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png  String userName

=

request.getParameter(

"

userName

"

);

d18c02628675d0a2c816449d98bda930.png  String password

=

request.getParameter(

"

password

"

);

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif

if

(userName.equals(

"

dennis

"

)

&&

password.equals(

"

123

"

))

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png      request.setAttribute(

"

name

"

, name);

d18c02628675d0a2c816449d98bda930.png

return

ActionForward.SUCCESS;

//

登陆成功,返回success

ecedf933ec37d714bd4c2545da43add2.png

}

else

d18c02628675d0a2c816449d98bda930.png

return

ActionForward.FAIL;

//

否则,返回fail

ecedf933ec37d714bd4c2545da43add2.png

}

d18c02628675d0a2c816449d98bda930.png

8f1ba5b45633e9678d1db480c16cae3f.png}

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

2。还是先来看下两个模型:ActionForward和ActionModel,没什么东西,属性以及相应的getter,setter方法:

4f1150b881333f12a311ae9ef34da474.png

package

com.strutslet.model;

4f1150b881333f12a311ae9ef34da474.png

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

/** */

/**

d18c02628675d0a2c816449d98bda930.png * 类说明:转向模型

d18c02628675d0a2c816449d98bda930.png *

@author

dennis

d18c02628675d0a2c816449d98bda930.png *

8f1ba5b45633e9678d1db480c16cae3f.png *

*/

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

public

class

ActionForward

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png

private

String name;

//

forward的name

d18c02628675d0a2c816449d98bda930.png

private

String viewUrl;

//

forward的url

d18c02628675d0a2c816449d98bda930.png

public

static

final

ActionForward SUCCESS

=

new

ActionForward(

"

success

"

);

d18c02628675d0a2c816449d98bda930.png

public

static

final

ActionForward FAIL

=

new

ActionForward(

"

fail

"

);

d18c02628675d0a2c816449d98bda930.png 

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif

public

ActionForward(String name)

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png

this

.name

=

name;

ecedf933ec37d714bd4c2545da43add2.png }

d18c02628675d0a2c816449d98bda930.png

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif

public

ActionForward(String name, String viewUrl)

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png

super

();

d18c02628675d0a2c816449d98bda930.png

this

.name

=

name;

d18c02628675d0a2c816449d98bda930.png

this

.viewUrl

=

viewUrl;

ecedf933ec37d714bd4c2545da43add2.png }

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png

//

9b8a8a44dd1c74ae49c20a7cd451974e.pngname和viewUrl的getter和setter方法

d18c02628675d0a2c816449d98bda930.png

8f1ba5b45633e9678d1db480c16cae3f.png}

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png我们看到ActionForward预先封装了SUCCESS和FAIL对象。

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

//

ActionModel.java

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

package

com.strutslet.model;

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

import

java.util.Map;

4f1150b881333f12a311ae9ef34da474.png

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

/** */

/**

d18c02628675d0a2c816449d98bda930.png * 类说明:

d18c02628675d0a2c816449d98bda930.png *

@author

dennis

d18c02628675d0a2c816449d98bda930.png *

8f1ba5b45633e9678d1db480c16cae3f.png

*/

4f1150b881333f12a311ae9ef34da474.png

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

public

class

ActionModel

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png

private

String path;

//

action的path

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png

private

String className;

//

action的class

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png

private

Map

<

String, ActionForward

>

forwards;

//

action的forward

d18c02628675d0a2c816449d98bda930.png

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif

public

ActionModel()

9b8a8a44dd1c74ae49c20a7cd451974e.png

{}

d18c02628675d0a2c816449d98bda930.png 

d18c02628675d0a2c816449d98bda930.png

public

ActionModel(String path, String className,

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif   Map

<

String, ActionForward

>

forwards)

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png

super

();

d18c02628675d0a2c816449d98bda930.png

this

.path

=

path;

d18c02628675d0a2c816449d98bda930.png

this

.className

=

className;

d18c02628675d0a2c816449d98bda930.png

this

.forwards

=

forwards;

ecedf933ec37d714bd4c2545da43add2.png }

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png

//

9b8a8a44dd1c74ae49c20a7cd451974e.png相应的getter和setter方法

d18c02628675d0a2c816449d98bda930.png

8f1ba5b45633e9678d1db480c16cae3f.png}

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

3。知道了两个模型是什么样,也应该可以猜到我们的配置文件大概是什么样的了,与struts的配置文件格式类似:

4f1150b881333f12a311ae9ef34da474.png

xml version

=

"

1.0

"

encoding

=

"

UTF-8

"

?>

4f1150b881333f12a311ae9ef34da474.png

<

actions

>

4f1150b881333f12a311ae9ef34da474.png

<

action path

=

"

/login

"

4f1150b881333f12a311ae9ef34da474.png

class

=

"

com.strutslet.demo.LoginAction

"

>

4f1150b881333f12a311ae9ef34da474.png

<

forward name

=

"

success

"

url

=

"

hello.jsp

"

/>

4f1150b881333f12a311ae9ef34da474.png

<

forward name

=

"

fail

"

url

=

"

fail.jsp

"

/>

4f1150b881333f12a311ae9ef34da474.png

action

>

4f1150b881333f12a311ae9ef34da474.png

actions

>

path是在应用中将被调用的路径,class指定了调用的哪个action,forward元素指定了转向,比如我们这里如果是success就转向hello.jsp,失败的话转向fail.jsp,这里配置了demo用到的LoginAction。

4。Dispacher接口,主要是getNextPage方法,此方法负责获得下一个页面将导向哪里,提供给前端控制器转发。

4f1150b881333f12a311ae9ef34da474.png

package

com.strutslet.core;

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

import

javax.servlet.ServletContext;

4f1150b881333f12a311ae9ef34da474.png

import

javax.servlet.http.HttpServletRequest;

4f1150b881333f12a311ae9ef34da474.png

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

/** */

/**

d18c02628675d0a2c816449d98bda930.png * service to worker模式,提供给FrontController使用

d18c02628675d0a2c816449d98bda930.png * 负责流程转发

d18c02628675d0a2c816449d98bda930.png *

@author

dennis

d18c02628675d0a2c816449d98bda930.png *

8f1ba5b45633e9678d1db480c16cae3f.png

*/

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

public

interface

Dispatcher

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png

public

void

setServletContext(ServletContext context);

d18c02628675d0a2c816449d98bda930.png

public

String getNextPage(HttpServletRequest request,ServletContext context);

8f1ba5b45633e9678d1db480c16cae3f.png}

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

5。原先书中实现了一个WorkFlow的Dispatcher,按照顺序调用action,实现工作流调用。而我们所需要的是根据请求的path 调用相应的action,执行action的execute方法返回一个ActionForward,然后得到ActionForward的 viewUrl,将此viewUrl提供给前端控制器转发,看看它的getNextPage方法:

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

public

String getNextPage(HttpServletRequest request, ServletContext context)

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png  setServletContext(context);

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png  Map

<

String, ActionModel

>

actions

=

(Map

<

String, ActionModel

>

) context

d18c02628675d0a2c816449d98bda930.png    .getAttribute(Constant.ACTIONS_ATTR);

//

从ServletContext得到所有action信息

d18c02628675d0a2c816449d98bda930.png

String reqPath

=

(String) request.getAttribute(Constant.REQUEST_ATTR);

//

发起请求的path

d18c02628675d0a2c816449d98bda930.png

ActionModel actionModel

=

actions.get(reqPath);

//

根据path得到相应的action

d18c02628675d0a2c816449d98bda930.png

String forward_name

=

""

;

d18c02628675d0a2c816449d98bda930.png  ActionForward actionForward;

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif

try

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png   Class c

=

Class.forName(actionModel.getClassName());

//

每个请求对应一个action实例

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png   Action action

=

(Action) c.newInstance();

d18c02628675d0a2c816449d98bda930.png   actionForward

=

action.execute(request, context);

//

执行action的execute方法

d18c02628675d0a2c816449d98bda930.png

forward_name

=

actionForward.getName();

d18c02628675d0a2c816449d98bda930.png   

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif  }

catch

(Exception e)

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png   log.error(

"

can not find action

"

+

actionModel.getClassName());

d18c02628675d0a2c816449d98bda930.png   e.printStackTrace();

ecedf933ec37d714bd4c2545da43add2.png  }

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png  actionForward

=

actionModel.getForwards().get(forward_name);

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif

if

(actionForward

==

null

)

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png   log.error(

"

can not find page for forward

"

+

forward_name);

d18c02628675d0a2c816449d98bda930.png

return

null

;

ecedf933ec37d714bd4c2545da43add2.png  }

else

d18c02628675d0a2c816449d98bda930.png

return

actionForward.getViewUrl();

//

返回ActionForward的viewUrl

8f1ba5b45633e9678d1db480c16cae3f.png

}

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

6。前端控制器(FrontController),它的任务我们已经很清楚,初始化配置文件;存储所有action到 ServletContext供整个框架使用;得到发起请求的path,提供给Dispachter查找相应的action;调用Dispatcher,执行getNextPage方法得到下一个页面的url并转发:

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif

public

void

init()

throws

ServletException

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png

//

初始化配置文件

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png  ServletContext context

=

getServletContext();

d18c02628675d0a2c816449d98bda930.png  String config_file

=

getServletConfig().getInitParameter(

"

config

"

);

d18c02628675d0a2c816449d98bda930.png  String dispatcher_name

=

getServletConfig().getInitParameter(

"

dispatcher

"

);

d18c02628675d0a2c816449d98bda930.png

if

(config_file

==

null

||

config_file.equals(

""

))

d18c02628675d0a2c816449d98bda930.png   config_file

=

"

/WEB-INF/strutslet-config.xml

"

;

//

默认是/WEB-INF/下面的strutslet-config

d18c02628675d0a2c816449d98bda930.png

if

(dispatcher_name

==

null

||

dispatcher_name.equals(

""

))

d18c02628675d0a2c816449d98bda930.png   dispatcher_name

=

Constant.DEFAULT_DISPATCHER;

d18c02628675d0a2c816449d98bda930.png    

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif

try

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png   Map

<

String, ActionModel

>

resources

=

ConfigUtil.newInstance()

//

工具类解析配置文件

d18c02628675d0a2c816449d98bda930.png

.parse(config_file, context);

d18c02628675d0a2c816449d98bda930.png   context.setAttribute(Constant.ACTIONS_ATTR, resources);

//

存储在ServletContext中

d18c02628675d0a2c816449d98bda930.png

log.info(

"

初始化strutslet配置文件成功

"

);

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif  }

catch

(Exception e)

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png   log.error(

"

初始化strutslet配置文件失败

"

);

d18c02628675d0a2c816449d98bda930.png   e.printStackTrace();

ecedf933ec37d714bd4c2545da43add2.png  }

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png

//

实例化Dispacher

d18c02628675d0a2c816449d98bda930.png

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif

try

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png   Class c

=

Class.forName(dispatcher_name);

d18c02628675d0a2c816449d98bda930.png      Dispatcher dispatcher

=

(Dispatcher) c.newInstance();

d18c02628675d0a2c816449d98bda930.png      context.setAttribute(Constant.DISPATCHER_ATTR, dispatcher);

//

放在ServletContext

d18c02628675d0a2c816449d98bda930.png

log.info(

"

初始化Dispatcher成功

"

);

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif  }

catch

(Exception e)

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png    log.error(

"

初始化Dispatcher失败

"

);

d18c02628675d0a2c816449d98bda930.png      e.printStackTrace();

ecedf933ec37d714bd4c2545da43add2.png  }

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png  

9b8a8a44dd1c74ae49c20a7cd451974e.png..

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png

doGet()和doPost方法我们都让它调用process方法:

4f1150b881333f12a311ae9ef34da474.png

protected

void

process(HttpServletRequest request,

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif   HttpServletResponse response)

throws

ServletException, IOException

9b8a8a44dd1c74ae49c20a7cd451974e.png

{

d18c02628675d0a2c816449d98bda930.png  ServletContext context

=

getServletContext();

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png

//

获取action的path

d18c02628675d0a2c816449d98bda930.png

String reqURI

=

request.getRequestURI();

d18c02628675d0a2c816449d98bda930.png

int

i

=

reqURI.lastIndexOf(

"

.

"

);

d18c02628675d0a2c816449d98bda930.png  String contextPath

=

request.getContextPath();

d18c02628675d0a2c816449d98bda930.png  String path

=

reqURI.substring(contextPath.length(),i);

d18c02628675d0a2c816449d98bda930.png  

d18c02628675d0a2c816449d98bda930.png  request.setAttribute(Constant.REQUEST_ATTR, path);

d18c02628675d0a2c816449d98bda930.png  Dispatcher dispatcher

=

(Dispatcher) context.getAttribute(Constant.DISPATCHER_ATTR);

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png

//

make sure we don't cache dynamic data

d18c02628675d0a2c816449d98bda930.png

response.setHeader(

"

Cache-Control

"

,

"

no-cache

"

);

d18c02628675d0a2c816449d98bda930.png  response.setHeader(

"

Pragma

"

,

"

no-cache

"

);

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png

//

use the dispatcher to find the next page

d18c02628675d0a2c816449d98bda930.png

String nextPage

=

dispatcher.getNextPage(request, context);

//

调用Dispatcher的getNextPage

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png

//

forward control to the view

d18c02628675d0a2c816449d98bda930.png

RequestDispatcher forwarder

=

request.getRequestDispatcher(

"

/

"

d18c02628675d0a2c816449d98bda930.png

+

nextPage);

d18c02628675d0a2c816449d98bda930.png  forwarder.forward(request, response);

//

转发页面

8f1ba5b45633e9678d1db480c16cae3f.png

}

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

7。最后,web.xml的配置就非常简单了,配置前端控制器,提供启动参数(配置文件所在位置,为空就查找/WEB-INF/下面的strutslet-config.xml文件),我们把所有以action结尾的请求都交给FrontController处理:

4f1150b881333f12a311ae9ef34da474.png

<

servlet

>

4f1150b881333f12a311ae9ef34da474.png

<

servlet

-

name

>

StrutsletController

servlet

-

name

>

4f1150b881333f12a311ae9ef34da474.png

<

servlet

-

class

>

com.strutslet.core.FrontController

servlet

-

class

>

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.png

<

load

-

on

-

startup

>

0

load

-

on

-

startup

>

4f1150b881333f12a311ae9ef34da474.png

servlet

>

4f1150b881333f12a311ae9ef34da474.png

<

servlet

-

mapping

>

4f1150b881333f12a311ae9ef34da474.png

<

servlet

-

name

>

StrutsletController

servlet

-

name

>

4f1150b881333f12a311ae9ef34da474.png

<

url

-

pattern

>*

.action

url

-

pattern

>

4f1150b881333f12a311ae9ef34da474.png

servlet

-

mapping

>

最后,让我们看看整个框架图:

0b813ee676670bfba025730baac1ffa4.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值