Spring MVC

SpringMVC 是一个包含了 Dispatcher servlet 的 MVC 框架,它调用控制器方法并转发到视图,

SpringMVC 能够加速开发的功能列表:

1. SpringMVC 中提供了一个开箱即用 Dispatcher servlet,无需额外开发。

2. SpringMVC 中使用基于 XML 的配置文件,可以编辑,而无需重新编译应用程序。

3. SpringMVC 实例化控制器,并根据用户输入来构造 bean

4. SpringMVC 可以自动绑定用户输入,并正确地转换数据类型。例如,SpringMVC 能够自动解析字符串,并设置 float 或 decimal 类型的属性

5. SpringMVC 内置了常见的校验器,可以校验用户输入,若校验不通过,则重定向会输入表单。输入校验是可选的,支持编程以及声明方式

6. SpringMVC 是 Spring 框架的一部分,可以利用 Spring 提供的其他能力

7. SpringMVC 支持国际化和本地化,支持根据用户区域显示多国语言

8. SpringMVC 支持多种视图技术,如 JSP、Velocity、FreeMarker

 

Spring MVC的配置可以分为基于 XML 的配置文件和注解(Spring 2.5之后)来管理应用中所用的 bean。

 

Spring MVC 的 DispatcherServlet

org.spring.framework.web.servlet.DispatcherServlet

要使用这个 Servlet,需要将其配置到部署描述符(web.xml)中,使用 <servlet> 元素和 <servlet-mapping> 元素,如下

<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>  <!-- 可选项,存在表名将在应用程序启动时装载Servlet并调用其init()方法;若不存在则在该servlet的第一次请求时加载 -->
</servlet>
  
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>  <!-- 该 Servlet 处理所有的请求 -->
</servlet-mapping>

Spring MVC 的配置文件

Dispatcher Servlet 会在应用中寻找一个 Spring MVC 的配置文件,该配置文件的默认命名和默认位置为:

/WEB-INF/servletName-servlet.xml  // servletName是部署描述符中 <servlet-name> 元素的值

也可以通过部署描述符的 <init-param> 元素修改 Spring MVC 配置文件的名称和位置,可以放置在应用程序目录中的任何地方。

<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/config/springmvc-config.xml</param-value>  <!-- Spring MVC 配置文件的位置和名称 -->
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>

Spring MVC 的 Controller 接口

在 Spring 2.5 以前,开发一个控制器的唯一方法是实现 org.springframework.web.servlet.mvc.Controller 接口,该接口公开了一个方法

ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws java.lang.Exception  // 

Controller 接口的实现类可以访问对应请求的 httpServletRequest 和 HttpServletResponse,还必须返回一个包含视图路径或视图路径和模型的 ModelAndView 对象。

Controller 接口的实现类只能处理一个单一动作(action),而一个基于注解的控制器可以同时支持多个请求处理动作,并且无需实现任何接口。

Spring MVC 中的视图解析器

org.springframework.web.servlet.view.InternalResourceViewResolver

视图解析器负责解析视图,可以通过在 Spring MVC 的配置文件中定义一个 ViewResolver 来配置视图解析器。

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/" />
    <property name="suffix" value=".jsp" />
</bean>

采用视图解析器后,在控制器类中只需要提供视图名称即可,视图解析器会自动加前缀和后缀。

例如,视图名为 ProductDetails,经过视图解析器处理后变为 /WEB-INF/jsp/ProductDetails.jsp

一个 Spring MVC 的简单应用(未使用视图解析器)

目录结构

部署描述符(web.xml)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
                             http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" 
                             version="4.0">
  
  <servlet>
      <servlet-name>springmvc</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <load-on-startup>1</load-on-startup>  <!-- 该元素是可选的 -->
  </servlet>
  
  <servlet-mapping>
      <servlet-name>springmvc</servlet-name>
      <url-pattern>/</url-pattern>  <!-- 该 Servlet 处理所有的请求 -->
  </servlet-mapping>
  
</web-app>

Spring MVC 的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean name="/product_input.action" class="app17a.controller.InputProductController" />       
    <bean name="/product_save.action" class="app17a.controller.SaveProductController" />
</beans>

app17a.controller.InputProductController类

package app17a.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class InputProductController implements Controller {
    private static final Log logger = LogFactory.getLog(InputProductController.class);
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("InputProductController called");
        return new ModelAndView("/WEB-INF/jsp/ProductForm.jsp");
    }
}

app17a.controller.SaveProductController类

package app17a.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import app17a.domain.Product;
import app17a.form.ProductForm;

public class SaveProductController implements Controller {
    private static final Log logger = LogFactory.getLog(SaveProductController.class);
    
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("SaveProductController called");
        ProductForm productForm = new ProductForm();
        productForm.setName(request.getParameter("name"));
        productForm.setDescription(request.getParameter("description"));
        productForm.setPrice(request.getParameter("price"));
        Product product = new Product();
        product.setName(productForm.getName());
        product.setDescription(productForm.getDescription());
        try {
            product.setPrice(Float.parseFloat(productForm.getPrice()));
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        return new ModelAndView("/WEB-INF/jsp/ProductDetails.jsp", "product", product);
    }
}

app17a.domain.Product类

package app17a.domain;

import java.io.Serializable;

public class Product implements Serializable { // 一个JavaBean 实现该接口,其实例可以安全的将数据保存到 HttpSession 中。
    private static final long serialVersionUID = 1L;
    private String name;
    private String description;
    private float price;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public float getPrice() {
        return price;
    }
    public void setPrice(float price) {
        this.price = price;
    }
}

app17a.form.ProductForm类

package app17a.form;

// 表单类与 HTML表单相映射,是HTML表单在服务端的代表
public class ProductForm {  // 表单类不需要实现 Serializable 接口,因为表单对象很少保存在 HttpSession 中。
    private String name;
    private String description;
    private String price;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public String getPrice() {
        return price;
    }
    public void setPrice(String price) {
        this.price = price;
    }
}

ProductForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Add Product Form</title>
    <link type="text/css" rel="stylesheet" href="css/main.css" />
</head>
<body>
    <div id="global">
        <form action="product_save.action" method="post">
            <fieldset>
                <legend>Add a product</legend>
                <p>
                <label for="name">Product Name: </label>
                <input type="text" id="name" name="name" value="" tabindex="1" />
                </p>
                <p>
                <label for="description">Description: </label>
                <input type="text" id="description" name="description" tabindex="2" />
                </p>
                <p>
                <label for="price">Price: </label>
                <input type="text" id="price" name="price" tabindex="3" />
                </p>
                <div id="buttons">
                    <label for="dummy"> </label>
                    <input type="reset" id="reset" tabindex="4" />
                    <input type="submit" id="submiy" tabindex="5" />
                </div>
            </fieldset>
        </form>
    </div>
</body>
</html>

ProductDetails.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Save Product</title>
    <link type="text/css" rel="stylesheet" href="css/main.css" />
</head>
<body>
    <div id="global">
        <h4>The Product has been saved.</h4>
        <p>
            <h5>Details:</h5>
            Product Name: ${product.name } <br />
            Description: ${product.description } <br />
            Price: $${product.price }  
        </p>
    </div>
</body>
</html>

测试结果

使用视图解析器的 Spring MVC 应用

目录结构

部署描述符(web.xml)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" 
         version="4.0">
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/config/springmvc-config.xml</param-value>  <!-- Spring MVC 配置文件的位置和名称 -->
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.action</url-pattern>  
    </servlet-mapping>

Spring MVC 配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean name="/product_input.action" class="app17b.controller.InputProductController" />       
    <bean name="/product_save.action" class="app17b.controller.SaveProductController" />
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
    
</beans>

其他文件内容不变,测试效果一样。

 

posted on 2018-10-30 11:04  0820LL  阅读(158)  评论(0编辑  收藏  举报

导航