ControllerAdvice-使用演示

3次阅读

共计 21033 个字符,预计需要花费 53 分钟才能阅读完成。

ControllerAdvice 控制器切面演示程序

在 spring 3.2 中,新增了 @ControllerAdvice 注解,并应用到所有 @RequestMapping 中,
可以用于定义

  • @ExceptionHandler 处理异常情况,根据异常类型选择处理方法;
  • @InitBinder 数据类型转换等,如前端请求所有参数都是字符串,后端需要日期,则可以在此设定统一转换格式;
  • @ModelAttribute 视图中共用的变量。

@ControllerAdvice 定义了多个时,通过 @Order/@Priority 指定执行顺序。

问题 1:如何根据前端要求返回不同的数据类型,如如 html 或 json?

@ExceptionHandler 需要返回不同类型数据,如 html 或 json,可以通过forward:error 实现,forward:error 会进入

org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController

里面分别有:

@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
    public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {HttpStatus status = getStatus(request);
        Map<String, Object> model = Collections
                .unmodifiableMap(getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
        response.setStatus(status.value());
        ModelAndView modelAndView = resolveErrorView(request, response, status, model);
        return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);
    }

    @RequestMapping
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL));
        HttpStatus status = getStatus(request);
        return new ResponseEntity<>(body, status);
    }

方法。
但进入这个 Contrller 有个前提,是要设置 request.setAttribute(“javax.servlet.error.status_code”, 500);

用户名输入 exception, 触发后端报错,可以比较 提交 Json 提交 返回数据的差别。

问题 2:如何将 json 改为 jsonp 支持跨域?

可以通过 ResponseBodyAdvice 我们可以很方便的将 json 数据改成 jsonp 进行返回。读者可自行尝试。

问题 3:相较 Controller, ControllerAdvice 执行的时机是什么?

InitBinder 与 ModelAttribute 在 Controller 方法之前执行,ExceptionHandler 在发生异常时执行。

附件 Spring MVC 之处理程序映射详解:

Spring MVC HandlerMappings 处理程序映射详解

HandlerMappings 解决的问题是 http 请求的 url 对应处理的 controller 类或方法的映射关系查找, 也就是

输入 URL -> 输出 Controller(或 Controller 的方法)

本项目中 DispatcherServlet 中涉及的 HandlerMappings

如果断点在 DispatcherServlet.doDispatch 的 getHandler 上,会发现有以下变理值
this.handlerMappings
0 = {SimpleUrlHandlerMapping@6497}
1 = {RequestMappingHandlerMapping@6498}
2 = {BeanNameUrlHandlerMapping@6499}
3 = {SimpleUrlHandlerMapping@6500}
4 = {WelcomePageHandlerMapping@6501}

下面对这几类映射方式作一下简单介绍.

HandlerMapping 是一个由定义请求和处理程序对象之间映射的对象实现的接口。默认情况下,DispatcherServlet 使用 BeanNameUrlHandlerMapping 和 DefaultAnnotationHandlerMapping。在 Spring 中,我们主要使用以下处理程序映射

  • BeanNameUrlHandlerMapping, bean name 作为 url 映射
  • ControllerClassNameHandlerMapping, Controller 小写名字作为 url, 新版本中已去掉
  • SimpleUrlHandlerMapping, url 和 controller 映射关系保存在配置列表中
  • DefaultAnnotationHandlerMapping, 新版本 (>3.2) 中已由 RequestMappingHandlerMapping 替换
  • RequestMappingHandlerMapping, 注解方式映射, 这里请求映射到 方法 ,其他几个是映射到
  • WelcomePageHandlerMapping, 主要用于访问根目录 ”/” 时跳转到相应的 index.html 或 index 视图模板

当容器中有多个 handlerMapping 实例时,会根据实例的优先级从高到底依次遍历,一旦找到对应 handler 后就会结束。优先级通过 mapping 的 order 属性设置,值越小,优先级越高。若不显示设置,默认就是 max,即优先级最低。范围 Ordered.HIGHEST_PRECEDENCE — Ordered.LOWEST_PRECEDENCE

Spring MVC RequestMappingHandlerMapping 示例

这是现在用得最多的一种,如下所示:

 @Controller
 @RequestMapping("/")
 public class MyController{@RequestMapping(value="/user/adduser", method={RequestMethod.POST})
  public ModelAndView mymethod(){return new ModelAndView("myview");
  }
}

本文不做详细介绍。

Spring MVC BeanNameUrlHandlerMapping 示例

在本文的 BeanNameUrlHandlerMapping 中。在这里,我们将每个请求直接映射到 Bean。

下面演示 BeanNameUrlHandlerMapping 使用。在这里,我们将直接将每个请求映射到 Bean,如下所示

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
     <bean name="/helloWorld.htm" 
          class="com.github.yujiaao.HelloWorldController" />
     <bean name="/hello*.htm" 
         class="com.github.yujiaao.HelloWorldController" />

在这里,我们可以看到我们提到了使用 BeanNameUrlHandlerMapping 的 Spring 容器,并且已经将每个可能的请求映射到控制器。

  1. 文件夹结构:创建一个动态 Web 项目“SpringMVCHandlerMappingTutorial”,并为我们的 src 文件下“com.github.yujiaao”创建一个包;
  2. 将 Spring 3 jar 文件放在 WEB-INF/lib 下

    commons-logging-1.1.1.jar
    log4j-1.2.16.jar
    slf4j-api-1.7.5.jar
    slf4j-log4j12-1.7.5.jar
    spring-aspects-3.2.4.RELEASE.jar
    spring-beans-3.2 .4.RELEASE.jar
    spring-context-3.2.4.RELEASE.jar
    spring-core-3.2.4.RELEASE.jar
    spring-expression-3.2.4.RELEASE.jar
    spring-web-3.2.4.RELEASE.jar
    spring-webmvc-3.2.4.RELEASE.jar

  3. 在 com.github.yujiaao 文件夹下创建 Java 类 HelloWorldController.java 和 WelcomeController.java;
  4. 将 SpringConfig-servlet.xml 和 web.xml 放在 WEB-INF 目录下;
  5. 视图模板文件 helloWorld.jsp 和 welcome.jsp 放在 WEB-INF/jsp 下的子目录下。

HelloWorldController.java

我们的 HelloWorldController 类扩展了 AbstractController 类,并覆盖了“handleRequestInternal()”方法。在方法内部,我们将创建一个 ModelAndView 对象,该对象具有重定向页面(helloWorld),并且用户传递一个将在视图页面上使用的 String。

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class HelloWorldController extends AbstractController
{

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request,
            HttpServletResponse response) throws Exception {System.out.println("Inside HelloWorldController");
        ModelAndView model = new ModelAndView("helloWorld");
        model.addObject("msg", "HandlerMappingDemo");
        
        return model;
    }
}

WelcomeController.java

WelcomeController 与 HelloWorldController 几乎相同,除了重定向页面和传递的 String。

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class WelcomeController extends AbstractController
{
    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request,
            HttpServletResponse response) throws Exception {System.out.println("Inside WelcomeController");

        ModelAndView model = new ModelAndView("welcome");
        model.addObject("msg", "HandlerMappingDemo");
        
        return model;
    }
}

helloWorld.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
       <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
       <title>Insert title here</title>
    </head>
    <body>
       <h2>Hello World ${msg}</h2> 
    </body>
</html>

welcome.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <title>Insert title here</title>
    </head>
    <body>
        <h2> Welcome to ${msg}</h2>
    </body>
</html>

web.xml

web.xml 包含服务器需要了解的有关应用程序的所有内容,这些内容位于 WEB-INF 目录下。<servlet-name> 包含 SpringConfiguration 的名称,初始化 DispatcherServlet 时,框架将尝试在 WEB-INF 目录下加载配置文件“[servlet-name] -servlet.xml”。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>SpringMVCFormHandling</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
    <servlet>
        <servlet-name>SpringConfig</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringConfig</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

SpringConfig-servlet.xml

该 SpringConfig-servlet.xml 中也被放置在 WEB-INF 目录下。
在这里,我们已将 BeanNameUrlHandlerMapping 配置为 HandlerMapping
每个请求也都映射到一个控制器

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
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-3.0.xsd    
http://www.springframework.org/schema/context    http://www.springframework.org/schema/context/spring-context-3.0.xsd    
http://www.springframework.org/schema/mvc    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> 
 
      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
         <property name="prefix" value="/WEB-INF/Jsp/"/>
         <property name="suffix" value=".jsp"/>
     </bean>
 
     <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
 
     <bean name="/helloWorld.htm" 
         class="com.github.yujiaao.HelloWorldController" />
 
     <bean name="/hello*" 
         class="com.github.yujiaao.HelloWorldController" /> 

     <bean name="/welcome.htm"
         class="com.github.yujiaao.WelcomeController"/>
 
</beans>

在上面的例子中

请求 helloWorld.htm 时,DispatcherServlet 将其重定向到 HelloWorldController。
请求 hello123 时,DispatcherServlet 将其重定向到 HelloWorldController。
请求 welcome.htm 时,DispatcherServlet 将其重定向到 WelcomeController。
请求 welcome123,因为没有映射,您将收到 404 错误。
输出量

当 HelloWorldController 调用时

Hello World HandlerMappingDemo

当 WelcomeController 调用时

Welcome to HandlerMappingDemo

Spring MVC ControllerClassNameHandlerMapping 示例

ControllerClassNameHandlerMapping 使用约定将请求的 URL 映射到 Controller。这将需要的控制器名称,并把它们转换成 小写了领先的“/”

上一个例子中,我们了解了 BeanNameUrlHandlerMapping 的工作方式。现在,让我们看一下 ControllerClassHandlerMapping,这种类型的 HandlerMapping 使用约定将请求的 URL 映射到 Controller。这将需要的控制器名称,并把它们转换成“/”开头小写了的名字。

Using BeanNameUrlHandlerMapping

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean name="/helloWorld.htm" 
     class="com.github.yujiaao.HelloWorldController" />
<bean name="/hello*.htm" 
     class="com.github.yujiaao.HelloWorldController" />  
Using ControllerClassNameHandlerMapping

 <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />
 <bean class="com.github.yujiaao.HelloWorldController"></bean>
 <bean class="com.github.yujiaao.WelcomeController"></bean>

使用 ControllerClassNameHandlerMapping 时,不需要 bean 名称

  1. 文件夹结构:创建一个动态 Web 项目“SpringMVCHandlerMappingTutorial”,并为我们的 src 文件“com.github.yujiaao”创建一个包;
  2. 将 Spring 3 jar 文件放在 WEB-INF/lib 下

    commons-logging-1.1.1.jar
    log4j-1.2.16.jar
    slf4j-api-1.7.5.jar
    slf4j-log4j12-1.7.5.jar
    spring-aspects-3.2.4.RELEASE.jar
    spring-beans-3.2.4.RELEASE.jar
    spring-context-3.2.4.RELEASE.jar
    spring-core-3.2.4.RELEASE.jar
    spring-expression-3.2.4.RELEASE.jar
    spring-web-3.2.4.RELEASE.jar
    spring-webmvc-3.2.4.RELEASE.jar

  3. 在 com.github.yujiaao 文件夹下 创建 Java 类 HelloWorldController.java 和 WelcomeController.java。
  4. 将 SpringConfig-servlet.xml 和 web.xml 放在 WEB-INF 目录下
  5. 视图模板文件 helloWorld.jsp 和 welcome.jsp 放在 WEB-INF/jsp 下的子目录下

HelloWorldController.java

我们的 HelloWorldController 类扩展了 AbstractController 类,并覆盖了“handleRequestInternal()”方法。在方法内部,我们将创建一个 ModelAndView 对象,该对象具有重定向页面(helloWorld),并且传递一个将在视图页面使用的 String msg。

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class HelloWorldController extends AbstractController
{

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request,
            HttpServletResponse response) throws Exception {System.out.println("Inside HelloWorldController");
        ModelAndView model = new ModelAndView("helloWorld");
        model.addObject("msg", "HandlerMappingDemo");
        
        return model;
    }
}

WelcomeController.java

WelcomeController 与 HelloWorldController 几乎相同,除了重定向页面和传递的 String。

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class WelcomeController extends AbstractController
{
    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request,
            HttpServletResponse response) throws Exception {System.out.println("Inside WelcomeController");

        ModelAndView model = new ModelAndView("welcome");
        model.addObject("msg", "HandlerMappingDemo");
        
        return model;
    }
}

helloWorld.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
       <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
       <title>Insert title here</title>
    </head>
    <body>
       <h2>Hello World ${msg}</h2> 
    </body>
</html>

welcome.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <title>Insert title here</title>
    </head>
    <body>
        <h2> Welcome to ${msg}</h2>
    </body>
</html>

web.xml

web.xml 包含服务器需要了解的有关应用程序的所有内容,这些内容位于 WEB-INF 目录下。<servlet-name> 包含 SpringConfiguration 的名称,初始化 DispatcherServlet 时,框架将尝试在 WEB-INF 目录下加载配置文件“[servlet-name]-servlet.xml”。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>SpringMVCFormHandling</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
    <servlet>
        <servlet-name>SpringConfig</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringConfig</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

SpringConfig-servlet.xml

  • 该 SpringConfig-servlet.xml 中也被放置在 WEB-INF 目录下。
  • 在这里,我们已将 BeanNameUrlHandlerMapping 配置为 HandlerMapping
  • 每个请求也都映射到一个控制器
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
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-3.0.xsd    
http://www.springframework.org/schema/context    
http://www.springframework.org/schema/context/spring-context-3.0.xsd    
http://www.springframework.org/schema/mvc    
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> 
 
      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
         <property name="prefix" value="/WEB-INF/Jsp/"/>
         <property name="suffix" value=".jsp"/>
     </bean>
 
      <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />
      <bean class="com.github.yujiaao.HelloWorldController"></bean>
      <bean class="com.github.yujiaao.WelcomeController"></bean>
 
</beans>

在上面的例子中

  • 请求 helloworld 时,DispatcherServlet 将其重定向到 HelloWorldController。
  • 请求 helloworld123 时,DispatcherServlet 将其重定向到 HelloWorldController。
  • 请求 welcome 时,DispatcherServlet 将其重定向到 WelcomeController。
  • 请求 welcome123,DispatcherServlet 将其重定向到 WelcomeController。
  • 请求 helloWorld,您将收到 404 错误,因为“W”大写

HelloWorldController 调用时的输出

Hello World HandlerMappingDemo

当 WelcomeController 调用时

Welcome to HandlerMappingDemo


Spring MVC SimpleUrlHandlerMapping 示例

SimpleUrlHandlerMapping 是所有处理程序映射中最简单的映射,它允许您指定 URL 模式和显式处理程序.

之前我们已经了解了 Spring MVC BeanNameUrlHandlerMapping 和 Spring MVC ControllerClassNameHandlerMapping。现在让我们看一下 SimpleUrlHandlerMapping,这种类型的 HandlerMapping 是所有处理程序映射中最简单的,它允许您显式指定 URL 模式和处理程序
有两种定义 SimpleUrlHandlerMapping 的方法,即 使用 <value> 标签和 <props> 标签。SimpleUrlHandlerMapping 有一个称为映射的属性,我们将向其传递 URL 模式。

使用 <value> 标签

左侧的 URL 模式“=”右侧 bean 的 ID 或 name

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  <property name="mappings">
     <value>
        /welcome.htm=welcomeController
        /welcome*=welcomeController
        /hell*=helloWorldController
        /helloWorld.htm=helloWorldController
      </value>
    </property>
 </bean>

使用 <props> 标签

该属性的键是 URL 模式, 属性值是 bean 的引用或名称

 <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
       <props>
          <prop key="/welcome.htm">welcomeController</prop>
          <prop key="/welcome*">welcomeController</prop>
          <prop key="/helloworld">helloWorldController</prop>
          <prop key="/hello*">helloWorldController</prop>
          <prop key="/HELLOworld">helloWorldController</prop>
     </props>
   </property>
 </bean>

1. 文件夹结构:创建一个动态 Web 项目“SpringMVCHandlerMappingTutorial”,并为我们的 src 文件“com.github.yujiaao”创建一个包;

  1. 将 Spring 3 jar 文件放在 WEB-INF/lib 下

    commons-logging-1.1.1.jar
    log4j-1.2.16.jar
    slf4j-api-1.7.5.jar
    slf4j-log4j12-1.7.5.jar
    spring-aspects-3.2.4.RELEASE.jar
    spring-beans-3.2.4.RELEASE.jar
    spring-context-3.2.4.RELEASE.jar
    spring-core-3.2.4.RELEASE.jar
    spring-expression-3.2.4.RELEASE.jar
    spring-web-3.2.4.RELEASE.jar
    spring-webmvc-3.2.4.RELEASE.jar

  2. 在 com.github.yujiaao 文件夹下 创建 Java 类 HelloWorldController.java 和 WelcomeController.java。
  3. 将 SpringConfig-servlet.xml 和 web.xml 放在 WEB-INF 目录下
  4. 视图模板文件 helloWorld.jsp 和 welcome.jsp 放在 WEB-INF/jsp 下的子目录下

HelloWorldController.java

我们的 HelloWorldController 类扩展了 AbstractController 类,并覆盖了“handleRequestInternal()”方法。

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class HelloWorldController extends AbstractController
{

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request,
            HttpServletResponse response) throws Exception {System.out.println("Inside HelloWorldController");
        ModelAndView model = new ModelAndView("helloWorld");
        model.addObject("msg", "HandlerMappingDemo");
        
        return model;
    }
}

WelcomeController.java

WelcomeController 与 HelloWorldController 几乎相同,除了重定向页面和传递的 String。

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class WelcomeController extends AbstractController
{
    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request,
            HttpServletResponse response) throws Exception {System.out.println("Inside WelcomeController");

        ModelAndView model = new ModelAndView("welcome");
        model.addObject("msg", "HandlerMappingDemo");
        
        return model;
    }
}

helloWorld.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
       <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
       <title>Insert title here</title>
    </head>
    <body>
       <h2>Hello World ${msg}</h2> 
    </body>
</html>

welcome.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <title>Insert title here</title>
    </head>
    <body>
        <h2> Welcome to ${msg}</h2>
    </body>
</html>

web.xml

web.xml 包含服务器需要了解的有关应用程序的所有内容,这些内容位于 WEB-INF 目录下。<servlet-name> 包含 SpringConfiguration 的名称,初始化 DispatcherServlet 时,框架将尝试在 WEB-INF 目录下加载配置文件“[servlet-name] -servlet.xml”。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>SpringMVCFormHandling</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
    <servlet>
        <servlet-name>SpringConfig</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringConfig</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

SpringConfig-servlet.xml

  • 该 SpringConfig-servlet.xml 中也被放置在 WEB-INF 目录下。
  • 在这里,我们已将 SimpleUrlHandlerMapping 配置 为 HandlerMapping
  • 每个请求也都映射到一个控制器
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
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-3.0.xsd    
http://www.springframework.org/schema/context    
http://www.springframework.org/schema/context/spring-context-3.0.xsd    
http://www.springframework.org/schema/mvc    
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> 
 
      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
         <property name="prefix" value="/WEB-INF/Jsp/"/>
         <property name="suffix" value=".jsp"/>
     </bean>
 
     <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/welcome.htm">welcomeController</prop>
                <prop key="/welcome*">welcomeController</prop>
                <prop key="/helloworld">helloWorldController</prop>
                <prop key="/hello*">helloWorldController</prop>
                <prop key="/HELLOworld">helloWorldController</prop>
           </props>
       </property>
 </bean>
 
   <bean id="helloWorldController" class="com.github.yujiaao.HelloWorldController"></bean>
   <bean id="welcomeController" class="com.github.yujiaao.WelcomeController"></bean>
 </beans>

在上面的例子中

  • 请求 helloworld 时,DispatcherServlet 将其重定向到 HelloWorldController。
  • 请求 hello123 时,DispatcherServlet 将其重定向到 HelloWorldController。
  • 请求 HELLOworld 时,DispatcherServlet 将其重定向到 HelloWorldController。
  • 请求 welcome.htm 时,DispatcherServlet 将其重定向到 WelcomeController。
  • 请求 welcome123,DispatcherServlet 将其重定向到 WelcomeController。
  • 请求 hELLOWorld,您将收到 404 错误,因为我们为其添加了映射。

HelloWorldController 调用时的输出

Hello World HandlerMappingDemo

当 WelcomeController 调用时

Welcome to HandlerMappingDemo

正文完
 0