`
a393060727
  • 浏览: 1731 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

servlet mvc 其实SPRING mvc与这个也类似

阅读更多
MVC概述
比较Servlet和JSP可以看出,Servlet是在Java代码中嵌入HTML,而JSP则是在HTML中嵌入Java代码,两者的优缺点正好互补,如表7-1所示。

表7-1
  Servlet
JSP

编写Java代码
容易
困难

编写HTML代码
困难
容易


如果仅使用Servlet,则虽然应用程序逻辑编写简单,但是,编码输出的页面极其难以维护;如果仅使用JSP,则虽然简化了页面设计,但大量的Java代码将使得应用程序逻辑难以维护。

因此,若能将Servlet和JSP结合使用,使得Servlet和JSP各司其职,就能大大降低Web应用程序的开发难度。

MVC(Model-View- Controller)即模型-视图-控制器,这种模式最早由Smalltalk语言引入,作为应用程序界面的标准设计模式,其应用范围极为广泛。MVC 模式通过将显示界面分为3个核心模块(模型、视图和控制器),分别负责不同的任务,协作完成一次完整的请求/响应。

图7-15显示了MVC模式的响应流程。

随着Web应用开发的兴起,MVC也被引入了 Web应用程序中。由于Servlet是纯Java代码,因此适合担任控制器,控制请求的流程。Servlet通过查询模型的状态,获得需要的数据,然后传递结果给视图,由视图将页面渲染出来,返回给用户。由于JSP主要是HTML标签,因此适合作为视图,仅负责渲染出结果页面。

受到HTTP协议的限制,模型的状态如果发生了更改,无法主动通知视图,因此,每次请求必须由浏览器发起。相对于传统的主动MVC模式,在Web应用程序中必须使用被动的MVC模式,如图7-16所示。



在JavaEE Web模型中,一个HTTP请求可以以3种转发方式。

(1)Forward:将一个请求传递给另一个组件处理,可以是Servlet或JSP,而当前的组件将不再继续处理请求。这也是MVC模式中转发请求让视图来渲染模型时使用的方式。

(2)Include:将一个请求传递给另一个组件处理,但是其处理结果将被包含在当前组件的输出页面中,通常,Include方式用来包含网站每个页面都共享的页眉和页脚,但是许多网页编辑工具本身就支持页面模板,因此,Include方式的使用并不多。

(3)Error:当处理请求发生了异常时,将被导向到指定的错误页面。

JavaEE平台上已经有许多成熟的Web MVC框架,例如,Struts和WebWork,其原理大同小异。在介绍如何使用Spring的MVC框架前,有必要首先弄清楚MVC的实现原理。

根据MVC的设计思想,一个完整的HTTP请求需要经过以下几步处理。

① 所有的HTTP请求都将映射到一个Servlet上。

② Servlet根据URL选择合适的Controller来处理请求,获得返回的Model和View。

③ Servlet将Model绑定到Request中,然后交给View渲染。

④ View将渲染后的页面返回给用户,完成请求处理。

由于存在多个控制器,如果直接用 Servlet作为控制器,则需要实现多个Servlet,这会导致非常复杂的配置和大量的重复代码。因此,通常将Servlet作为一个请求入口,或者称之为前置控制器(Front Controller),然后根据URL选择一个合适的控制器处理,具体流程如图7-17所示。



由于Servlet需要知道URL和控制器的映射关系,所以还需要首先抽象出Controller。通常,在Web MVC框架中,我们将抽象的Controller称为控制器,将负责接收用户请求的Servlet称为前置控制器或请求转发器(DispatcherServlet)。下面,我们在Eclipse中建立一个SimpleMVC项目,自己动手实现一个最简单的MVC流程,如图 7-18所示。



图7-18

7.2.1  设计Controller
根据面向接口编程的良好实践,首先定义一个Controller接口。

public interface Controller {

    ModelAndView handleRequest(HttpServletRequest request,

            HttpServletResponse response) throws Exception;

}

Controller 需要返回视图和将要由视图渲染的Model。视图通常是JSP页面,因此,返回JSP页面的路径即可,而Model可以简单地使用Map来实现。由于一个方法只能返回一个对象,因此,有必要将Model和View一起返回。设计ModelAndView如下。

public class ModelAndView {

    private String view;

    private Map<String, Object> model;

    public ModelAndView(String view, Map<String, Object> model) {

        this.view = view;

        this.model = model;

    }

    public String getView() { return view; }

    public Map<String, Object> getModel() { return model; }

}

下一步是实现一个具体的TestController,它从request中获得URL的参数,然后生成Model并返回ModelAndView。

public class TestController implements Controller {

    public ModelAndView handleRequest(HttpServletRequest request, HttpServlet Response response) throws Exception {

        String name = request.getParameter("name");

        if(name==null) name = "world";

        Map<String, Object> model = new HashMap<String, Object>();

        model.put("message", "This is a TestController.");

        model.put("greet", "Hello, " + name + "!");

        model.put("time", new Date().toString());

        // 返回的JSP视图路径是"/test.jsp":

        return new ModelAndView("/test.jsp", model);

    }

}

在实现了Controller后,现在需要定义的就是如何在Servlet中控制整个请求的处理流程。

7.2.2  实现请求转发
通常,我们把接收所有请求的Servlet命名为DispatcherServlet,在SimpleMVC项目中,我们把所有以“.cmd”结尾的URL 都映射到DispatcherServlet,然后在DispatcherServlet中,根据URL选择合适的Controller,实现请求转发。我们假定现在定义了两个Controller:TestController和LoginController,其对应的URL分别是 “/test.cmd”和“/login.cmd”,在DispatcherServlet中处理如下。

public class DispatcherServlet extends HttpServlet {

    private ServletContext context;

    private Map<String, Controller> controllers;

    // 初始化DispatcherServlet:

    public void init(ServletConfig config) throws ServletException {

        context = config.getServletContext();

        // 将URL和对应的Controller关联起来:

        controllers = new HashMap<String, Controller>();

        controllers.put("/test.cmd", new TestController());

        controllers.put("/login.cmd", new LoginController());

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String contextPath = request.getContextPath();

        String uri = request.getRequestURI().substring(contextPath.length());

        Controller controller = controllers.get(uri);

        if(controller==null) {

            // 没有找到合适的Controller处理请求,直接返回一个404错误:

            response.sendError(404);

            return;

        }

        try {

            // 将请求交给Controller处理:

            ModelAndView mv = controller.handleRequest(request, response);

            // 将Model绑定到Request中:

            Map<String, Object> model = mv.getModel();

            Set<String> keys = model.keySet();

            for(String key : keys)

                request.setAttribute(key, model.get(key));

            // 获得JSP视图的路径:

            String jsp = mv.getView();

            // 转发给JSP视图渲染:

            context.getRequestDispatcher(jsp).forward(request, response);

        }

        catch(Exception e) {

            // 处理过程中发生异常,返回一个500错误:

            response.sendError(500);

        }

    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // POST请求的处理方式和GET一样:

        doGet(request, response);

    }

}

DispatcherServlet 将Controller返回的Model绑定到Request,然后使用forward()将Request交给JSP页面渲染。在JSP页面中,只需要使用JSP标签把Model的数据显示出来,因此,不需要也不应该嵌入任何Java代码。test.jsp页面源码如下。

<%@ page contentType="text/html; charset=utf-8" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>

<html>

    <head>

        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

        <title>TestController -&gt; test.jsp</title>

    </head>

    <body>

        <p>/test.cmd (TestController) -&gt; test.jsp </p>

        <p>Message: <c:out value="${message}" /></p>

        <p>Greet: <c:out value="${greet}" /></p>

        <p>Time: <c:out value="${time}" /></p>

    </body>

</html>

如果用户请求URL“/test.cmd?name=spring”,则整个请求按照以下流程处理,如图7-18所示。



LoginController则稍微复杂一点,它根据登录是否成功来决定返回哪一个ModelAnd View。

public class LoginController implements Controller {

    public ModelAndView handleRequest(HttpServletRequest request, HttpServlet Response response) throws Exception {

        String username = request.getParameter("username");

        String password = request.getParameter("password");

        if("admin".equals(username) && "password".equals(password)) {

            // 登录成功,将转入/welcome.jsp:

            Map<String, Object> model = new HashMap<String, Object>();

            model.put("username", username);

            model.put("greet", "Welcome!");

            model.put("time", new Date().toString());

            return new ModelAndView("/welcome.jsp", model);

        }

        // 登录失败,将转入/loginFailed.jsp:

        Map<String, Object> error = new HashMap<String, Object>();

        error.put("message", "Login failed.");

        error.put("time", new Date().toString());

        return new ModelAndView("/loginFailed.jsp", error);

    }

}

为了能在Resin中测试我们自己实现的这个SimpleMVC,需要在web.xml中注册DispatcherServlet,由于JSP页面还使用了JSTL标签库,因此,还要在web.xml中注册标签库。

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

    <servlet>

        <servlet-name>dispatcher</servlet-name>

        <servlet-class>example.chapter7.DispatcherServlet</servlet-class>

        <load-on-startup>0</load-on-startup>

    </servlet>

    <servlet-mapping>

        <servlet-name>dispatcher</servlet-name>

        <url-pattern>*.cmd</url-pattern>

    </servlet-mapping>

    <taglib>

        <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>

        <taglib-location>/WEB-INF/c.tld</taglib-location>

    </taglib>

</web-app>
分享到:
评论

相关推荐

    Servlet JSP和Spring MVC初学指南

    Servlet JSP和Spring MVC初学指南

    Servlet JSP Spring MVC初学指南(alin书签).pdf

    Servlet、JSP和Spring MVC是Java Web开发中的三个重要技术,它们在构建动态网页和企业级应用程序中扮演着核心角色。下面将详细解释这三个技术及其相互关系。 **Servlet** 是Java编程语言中的一种接口,由Java ...

    Servlet,JSP和Spring MVC 初学指南源码

    在这个名为“budi-kurniawan-servlet-jsp-springmvc-examples-4754f4ab5d5c”的压缩包中,可能包含了各种示例代码,涵盖了Servlet、JSP和Spring MVC的基本用法和组合应用。例如: 1. Servlet示例:展示了如何创建和...

    servlet JSP 和 spring MVC学习指南

    servlet , jsp和spring MVC学习指南电子书,spring MVC学习指南系列书籍。

    spring-webmvc5.3.6 jar包.rar

    这个jar文件包含Spring MVC框架相关的所有类。  包含国际化、标签、Theme、视图展现的FreeMarker、JasperReports、Tiles、Velocity、XSLT相关类。  当然,如果你的应用使用了独立的MVC框架,则无需这个JAR文件里的...

    Spring+Spring MVC+Spring JDBC+MySql实现简单登录注册

    这个简单的登录注册系统展示了Spring框架的强大功能,以及如何与其他技术如Spring MVC、Spring JDBC和MySQL协同工作,为开发者提供了一个完整的后端解决方案。通过深入理解并实践这些知识点,开发者能够构建更复杂的...

    spring2.0MVC+spring2.5MVC+portletMVC

    2. **portlet上下文**:与Servlet上下文类似,portlet上下文提供了portlet特有的配置和资源。 3. **portlet间通信**:通过PortletSession和PortletPreferences,portlet可以共享数据或设置用户偏好。 4. **portlet...

    基于Spring MVC + Spring + MyBatis的【学生管理管理系统】.zip.zip

    使用环境:MyEclipse/Eclipse + Tomcat + MySQL。 使用技术:Spring MVC + Spring + MyBatis / JSP + Servlet + JavaBean + JDBC。

    Spring mvc、 Spring、 Spring jdbc 整合实例源码

    1. **配置文件**:包括Spring的主配置文件(如`applicationContext.xml`),其中定义了Bean的配置,包括DataSource、JdbcTemplate或JpaTemplate等,以及Spring MVC的配置文件(如`servlet-context.xml`),定义了...

    Servlet+JSP和Spring+MVC初学指南 书籍配套源码

    Servlet+JSP与Spring+MVC是两种在Java Web开发中常见的技术栈,它们用于构建动态、交互式的Web应用程序。本指南将深入介绍这两种技术及其整合应用,通过配套的源码帮助初学者更好地理解概念和实践操作。 Servlet是...

    servlet及MVC学习实例

    Servlet和MVC(Model-View-Controller)是Java Web开发中的两个重要概念,它们在构建动态网站和应用程序中起着核心作用。在这个学习实例中,我们将会深入理解这两个概念,并通过具体的代码示例来加深理解。 Servlet...

    Spring mvc + Spring + Mybatis 整合demo

    在本文中,我们将深入探讨如何将Spring MVC、Spring和Mybatis这三大流行框架整合到一个Java Web项目中,创建一个高效、灵活的数据访问层。这个整合的Demo项目名为"ssm-demo",它是一个基于Maven构建的项目,这意味着...

    spring MVC配置详解

    Spring MVC 是一个基于 DispatcherServlet 的 MVC 框架,它是当前主流的 Web 框架之一。要想灵活运用 Spring MVC 来应对大多数的 Web 开发,就必须要掌握它的配置及原理。 一、Spring MVC 环境搭建 1. jar 包引入 ...

    Spring MVC+ Spring+ Mybatis 框架搭建

    这个案例可能包括了Spring MVC的Controller,Spring的配置文件,Mybatis的Mapper和XML文件,以及数据库相关的配置。通过分析这些文件,初学者可以了解SSM框架的基本结构和使用方法,例如请求处理、服务层调用、...

    servlet与spring整合例子

    在Servlet与Spring整合时,首先我们需要创建一个Spring配置文件(如`beans.xml`),在这个文件中定义bean的配置。然后在Web应用的`web.xml`中,通过`ContextLoaderListener`配置Spring上下文,使得在应用启动时...

    spring_MVC源码

    本文主要介绍使用注解方式配置的spring mvc,之前写的spring3.0 mvc和rest小例子没有介绍到数据层的内容,现在这一篇补上。下面开始贴代码。 文中用的框架版本:spring 3,hibernate 3,没有的,自己上网下。 先说...

    spring mvc jar包

    3. `org.springframework.web.servlet-3.0.2.RELEASE.jar`:这是 Spring MVC 的核心模块,提供了控制器(Controller)、模型视图(ModelAndView)以及调度器Servlet(DispatcherServlet)等关键组件。...

    基于Servlet实现的MVC项目demo

    虽然Servlet能实现MVC,但现代Java Web开发更多地使用Spring MVC、Struts等成熟的MVC框架,它们提供了更高级的功能,如自动绑定、拦截器、依赖注入等,使开发更高效,代码更简洁。 综上所述,"MVCDemo2"项目展示了...

    Spring Web MVC外文翻译

    与 Spring Web MVC 并行地,Spring Framework 5.0 引入了响应式栈——一个名为 Spring WebFlux 的 Web 框架,该框架的命名也是基于其源模块 `spring-webflux`。本节将重点讨论 Spring Web MVC。 #### 二、...

Global site tag (gtag.js) - Google Analytics