您的位置:首页 > 编程语言 > Java开发

Spring MVC 入门示例讲解

2017-02-08 14:31 453 查看
在本例中,我们将使用Spring MVC框架构建一个入门级web应用程序。Spring MVC 是Spring框架最重要的的模块之一。它以强大的Spring IoC容器为基础,并充分利用容器的特性来简化它的配置。

A. MVC框架是什么
模型-视图-控制器(MVC)是一个众所周知的以设计界面应用程序为基础的设计模式。它主要通过分离
1. 模型、
2. 视图及
3. 控制器
在应用程序中的角色将业务逻辑从界面中解耦。通常,
1. 模型负责封装应用程序数据在视图层展示。
2. 视图仅仅只是展示这些数据,不包含任何业务逻辑。
3. 控制器负责接收来自用户的请求,并调用后台服务(manager或者dao)来处理业务逻辑。
处理后,后台业务层可能会返回了一些数据在视图层展示。控制器收集这些数据及准备模型在视图层展示。
MVC模式的核心思想是将业务逻辑从界面中分离出来,允许它们单独改变而不会相互影响。

B. Spring MVC
在Spring MVC应用程序中,
1. 模型通常由POJO(Plain Ordinary Java Object, 简单普通JAVA对象)对象组成,它在业务层中被处理,在持久层中被持久化。
2. 视图通常是用JSP标准标签库(JSTL)编写的JSP模板。
3. 控制器部分是由dispatcher servlet负责,在本教程中我们将会了解更多它的相关细节。
一些开发人员认为业务层和DAO层类是MVC模型组件的一部分。其实不然, 对此持我有不同的意见。我不认为业务层及DAO层类为MVC框架的一部分。通常一个web应用是3层架构,即数据-业务-表示。MVC实际上是表示层的一部分。DAO属于ORM的一部分。

B.1 Dispatcher Servlet(Spring Controller)
在最简单的Spring MVC应用程序中,控制器是唯一的你需要在Java web部署描述文件(即web.xml文件)中配置的Servlet。Spring MVC控制器 ——通常称作Dispatcher Servlet,实现了前端控制器设计模式。并且每个web请求必须通过它以便它能够管理整个请求的生命周期。
1. 当一个web请求发送到Spring MVC应用程序,dispatcher servlet首先接收请求。
2. 然后它组织那些在Spring web应用程序上下文配置的(例如实际请求处理控制器和视图解析器)或者使用注解配置的组件,所有的这些都需要处理该请求。

在Spring3.0中定义一个控制器类,这个类必须标有@Controller注解。当有@Controller注解的控制器收到一个请求时,它会寻找一个合适的handler方法去处理这个请求。这就需要控制器通过一个或多个handler映射去把每个请求映射到handler方法。
3. Spring控制器类收到请求(这个类必须有@Controller注释)。
4. Controller找到一个合适的handler去处理这个请求。(控制器方法要有@RequestMapping注释修饰)
为了这样做,一个控制器类的方法需要被@RequestMapping注解装饰,使它们成为handler方法。
5.handler方法处理完请求后,它把控制权委托给视图名与handler方法返回值相同的视图。(说是handler处理完毕后返回一个字符串,在交给该字符串同名的视图么?)
但是这个视图不是真实的视图,有一个配置对应到真实的物理视图文件。这个对应在哪里呢?

为了提供一个灵活的方法,一个handler方法的返回值并不代表一个视图的实现而是一个逻辑视图,即没有任何文件扩展名。你可以将这些逻辑视图映射到正确的实现,并将这些实现写入到上下文文件,这样你就可以轻松的更改视图层代码甚至不用修改请求handler类的代码。
为一个逻辑名称匹配正确的文件是视图解析器的责任。一旦控制器类已将一个视图名称解析到一个视图实现。它会根据视图实现的设计来渲染对应对象。
Spring入门示例
在这个应用程序中,我将创建最简单的员工管理应用程序的演示,它只有一个功能,即系统提供的所有雇员的列表。让我们记下此应用程序的目录结构。

现在让我们编写所有涉及这个入门应用程序的文件。
pom.xml
以下pom.xml文件中包含spring mvc依赖及为编写jsp文件提供支持的taglib相关依赖,


<project xmlns="http://maven.apache.org/POM/4.0.0"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0  

  http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.howtodoinjava.demo</groupId>

<artifactId>springmvcexample</artifactId>

<packaging>war</packaging>

<version>1.0-SNAPSHOT</version>

<name>springmvcexample Maven Webapp</name>

<url>http://maven.apache.org</url>

<dependencies>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.12</version>

<scope>test</scope>

</dependency>

<!-- Spring MVC support -->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-webmvc</artifactId>

<version>4.1.4.RELEASE</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-web</artifactId>

<version>4.1.4.RELEASE</version>

</dependency>

<!-- Tag libs support for view layer -->

<dependency>

<groupId>javax.servlet</groupId>

<artifactId>jstl</artifactId>

<version>1.2</version>

<scope>runtime</scope>

</dependency>

<dependency>

<groupId>taglibs</groupId>

<artifactId>standard</artifactId>

<version>1.1.2</version>

<scope>runtime</scope>

</dependency>

</dependencies>

<build>

<finalName>springmvcexample</finalName>

</build>

</project>
web.xml
这最精简的web.xml文件声明了一个Servlet(即dispatcher servlet)来接收所有类型的请求。Dispatcher servlet在这里充当前端控制器的角色。 http://localhost:8080/springmvcexample/employee-module/getAllEmployees
<web-app id="WebApp_ID" version="2.4"

xmlns="http://java.sun.com/xml/ns/j2ee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring Web MVC Hello World Application</display-name>

<servlet>

     <servlet-name>spring</servlet-name>

     <servlet-class>org.springframework.web.servlet.DispatcherServlet

     </servlet-class>

     <load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

     <servlet-name>spring</servlet-name>

     <url-pattern>/</url-pattern>

</servlet-mapping>

</web-app>
spring-servlet.xml(你也可以用applicationContext.xml文件)
在请求handler、业务层、dao层,我们使用带注解的类,所以我为“com.howtodoinjava.demo”包里的所有类启用了注解处理

<beans xmlns="http://www.springframework.org/schema/beans"

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 xmlns:context="http://www.springframework.org/schema/context"

 xsi:schemaLocation="http://www.springframework.org/schema/beans

        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 <context:component-scan base-package="com.howtodoinjava.demo" />

 <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />

 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

 

 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

     <property name="prefix" value="/WEB-INF/views/" />

     <property name="suffix" value=".jsp" />

 </bean>

 

</beans>
注释: 在spring-servlet.xml配置文件中配置,spring可以自动去扫描base-package("com.howtodoinjava.demo")下面或者子包下面的java文件,如果扫描到有@Component,@Controller,@Service等这些注解的类,则把这些类注册为bean。即告诉Spring
该到哪里去找标记为@Controller 的Controller 控制器。

第一层
EmployeeController.java
注解@RequestMapping在类级别和方法级别层面确定将被调用方法的URL。例如: http://localhost:8080/springmvcexample/employee-module/getAllEmployees
package com.howtodoinjava.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import com.howtodoinjava.demo.service.EmployeeManager;

@Controller

@RequestMapping("/employee-module")

public class EmployeeController

{

    @Autowired

    EmployeeManager manager;

    @RequestMapping(value = "/getAllEmployees", method = RequestMethod.GET)

    public String getAllEmployees(Model model)

    {

        model.addAttribute("employees", manager.getAllEmployees());

        return "employeesListDisplay";

    }

}
注释:在此以后,控制权转向employeesListDispaly视图,并且传递了参数model. 有意思的是这里的EmployeeManager 数据结构居然是第2层的声明。

阅读更多:如何使用@Component、@Respository、@Service及@Controller注解
EmployeeVO.java
这个类作为MVC模式的模型。

package com.howtodoinjava.demo.model;

import java.io.Serializable;

public class EmployeeVO implements Serializable

{

    private static final long serialVersionUID = 1L;

    private Integer id;

    private String firstName;

    private String lastName;

    //Setters and Getters

    @Override

    public String toString() {

        return "EmployeeVO [id=" + id + ", firstName=" + firstName

            + ", lastName=" + lastName + "]";

    }

}
注释: 貌似现在没有什么用处,为了第2层的业务层服务的。

第二层
EmployeeManager.java
这个类处于三层架构中的第二层。负责与DAO层交互。

import java.util.List;

import com.howtodoinjava.demo.model.EmployeeVO;

public interface EmployeeManager

{

    public List<EmployeeVO> getAllEmployees();

}
EmployeeManagerImpl.java

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.howtodoinjava.demo.dao.EmployeeDAO;

import com.howtodoinjava.demo.model.EmployeeVO;

@Service

public class EmployeeManagerImpl implements EmployeeManager {

    @Autowired

    EmployeeDAO dao;

    public List<EmployeeVO> getAllEmployees()

    {

        return dao.getAllEmployees();

    }

}
第三层
EmployeeDAO.java
这个类位于三层架构中的第三层。负责与底层的数据库存储进行交互。

import java.util.List;

import com.howtodoinjava.demo.model.EmployeeVO;

public interface EmployeeDAO

{

    public List<EmployeeVO> getAllEmployees();

}
EmployeeDAOImpl.java

import java.util.ArrayList;

import java.util.List;

import org.springframework.stereotype.Repository;

import com.howtodoinjava.demo.model.EmployeeVO;

@Repository

public class EmployeeDAOImpl implements EmployeeDAO {

    public List<EmployeeVO> getAllEmployees()

    {

        List<EmployeeVO> employees = new ArrayList<EmployeeVO>();

    

        EmployeeVO vo1 = new EmployeeVO();

        vo1.setId(1);

        vo1.setFirstName("Lokesh");

        vo1.setLastName("Gupta");

        employees.add(vo1);

        EmployeeVO vo2 = new EmployeeVO();

        vo2.setId(2);

        vo2.setFirstName("Raj");

        vo2.setLastName("Kishore");

        employees.add(vo2);

        return employees;

    }

}
employeesListDisplay.jsp
这个jsp被用于显示系统中的所有员工。它循环遍历employee集合,并且在一个表中打印他们的详细信息。这符合MVC模式的视图层。

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

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

<html>

<head>

<title>Spring MVC Hello World</title>

</head>

<body>

<h2>All Employees in System</h2>

<table border="1">

<tr>

<th>Employee Id</th>

<th>First Name</th>

<th>Last Name</th>

</tr>

<c:forEach items="${employees}" var="employee">

<tr>

<td>${employee.id}</td>

<td>${employee.firstName}</td>

<td>${employee.lastName}</td>

</tr>

</c:forEach>

</table>

</body>

</html>
注释: employees是从EmployController.java调用的时候传过来的( model.addAttribute("employees", manager.getAllEmployees());)

现在在您的应用程序服务器(我用的是tomcat 7)部署应用程序。并点击“http://localhost:8080/springmvcexample/employee-module/getAllEmployees”。如果你已正确配置所有内容,你将会在屏幕下看到:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: