Quick Guide to Spring Controllers – Spring控制器快速指南

最后修改: 2016年 8月 2日


1. Introduction


In this article we’ll focus on a core concept in Spring MVC – Controllers.

在这篇文章中,我们将重点讨论Spring MVC的一个核心概念–控制器。

2. Overview


Let’s start by taking a step back and having a look at the concept of the Front Controller in the typical Spring Model View Controller architecture.

让我们先退一步,看看典型的Spring Model View Controller架构中的Front Controller的概念

At a very high level, here are the main responsibilities we’re looking at:


  • Intercepts incoming requests
  • Converts the payload of the request to the internal structure of the data
  • Sends the data to Model for further processing
  • Gets processed data from the Model and advances that data to the View for rendering

Here’s a quick diagram for the high level flow in Spring MVC:

下面是一张关于Spring MVC中高层流程的快速图表。


As you can see, the DispatcherServlet plays the role of the Front Controller in the architecture.

正如你所看到的,DispatcherServlet在架构中扮演Front Controller的角色。

The diagram is applicable both to typical MVC controllers as well as RESTful controllers – with some small differences (described below).


In the traditional approach, MVC applications are not service-oriented hence there is a View Resolver that renders final views based on data received from a Controller.

在传统方法中,MVC应用程序不是面向服务的,因此有一个View Resolver,它根据从Controller收到的数据渲染最终视图。

RESTful applications are designed to be service-oriented and return raw data (JSON/XML typically). Since these applications do not do any view rendering, there are no View Resolvers – the Controller is generally expected to send data directly via the HTTP response.


Let’s start with the MVC0-style controllers.


3. Maven Dependencies


In order to be able to work with Spring MVC, let’s deal with the Maven dependencies first:

为了能够使用Spring MVC,让我们先处理一下Maven的依赖性。


To get the latest version of the library, have a look at spring-webmvc on Maven Central.


4. Project Web Config


Now, before looking at the controllers themselves, we first need to set up a simple web project and do a quick Servlet configuration.


Lets first see how the DispatcherServlet can be set up without using web.xml – but instead using an initializer:


public class StudentControllerConfig implements WebApplicationInitializer {

    public void onStartup(ServletContext sc) throws ServletException {
        AnnotationConfigWebApplicationContext root = 
          new AnnotationConfigWebApplicationContext();


        sc.addListener(new ContextLoaderListener(root));

        DispatcherServlet dv = 
          new DispatcherServlet(new GenericWebApplicationContext());

        ServletRegistration.Dynamic appServlet = sc.addServlet("test-mvc", dv);

To set things up with no XML, make sure to have servlet-api 3.1.0 on your classpath.

要在没有XML的情况下进行设置,确保你的classpath上有servlet-api 3.1.0。

Here’s how the web.xml would look like:



We’re setting the contextConfigLocation property here – pointing to the XML file used to load the Spring context. If the property is not there, Spring will search for a file named {servlet_name}-servlet.xml.


In our case the servlet_name is test-mvc and so, in this example the DispatcherServlet would search for a file called test-mvc-servlet.xml.


Finally, let’s set the DispatcherServlet up and map it to a particular URL – to finish our Front Controller based system here:

最后,让我们设置DispatcherServlet,并将其映射到一个特定的URL–以完成我们基于Front Controller的系统。


Thus in this case the DispatcherServlet would intercept all requests within the pattern /test/* .


5. Spring MVC Web Config

5.Spring MVC Web配置

Lets now look at how the Dispatcher Servlet can be setup using Spring Config:

现在让我们来看看如何使用Spring Config来设置Dispatcher Servlet

@ComponentScan(basePackages= {
  "com.baeldung.controller.config" }) 
public class WebConfig implements WebMvcConfigurer {
    public void configureDefaultServletHandling(
      DefaultServletHandlerConfigurer configurer) {
    public ViewResolver viewResolver() {
        InternalResourceViewResolver bean = 
          new InternalResourceViewResolver();
        return bean;

Let’s now look at setting up the Dispatcher Servlet using XML . A snapshot of the DispatcherServlet XML file – the XML file which the DispatcherServlet uses for loading custom controllers and other Spring entities is shown below:

现在让我们看看如何使用XML设置Dispatcher Servlet。下面是DispatcherServlet XML文件的快照–DispatcherServlet用于加载自定义controller和其他Spring实体XML文件。

<context:component-scan base-package="com.baledung.controller" />
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix">
    <property name="suffix">

Based on this simple configuration, the framework will of course initialize any controller bean that it will find on the classpath.


Notice that we’re also defining the View Resolver, responsible for view rendering – we’ll be using Spring’s InternalResourceViewResolver here. This expects a name of a view to be resolved, which means finding a corresponding page by using prefix and suffix (both defined in the XML configuration).

请注意,我们还定义了负责视图渲染的视图解析器 – 我们将在此使用Spring的InternalResourceViewResolver。这期望一个视图的名字被解析,这意味着通过使用前缀和后缀(都在 XML配置中定义)找到一个相应的页面。

So for example if the Controller returns a view named “welcome”, the view resolver will try to resolve a page called “welcome.jsp” in the WEB-INF folder.

因此,例如,如果Controller返回一个名为”welcome “的viewviewresolver将尝试解析WEB-INF文件夹中一个名为“welcome.jsp “的页面。

6. The MVC Controller


Let’s now finally implement the MVC style controller.


Notice how we’re returning a ModelAndView object – which contains a model map and a view object; both will be used by the View Resolver for data rendering:

注意我们是如何返回一个ModelAndView对象的–它包含一个model map和一个view object;两者都将被View Resolver用于数据渲染。

@RequestMapping(value = "/test")
public class TestController {

    public ModelAndView getTestData() {
        ModelAndView mv = new ModelAndView();
        mv.getModel().put("data", "Welcome home man");

        return mv;

So, what exactly did we set up here.


First, we created a controller called TestController and mapped it to the “/test” path. In the class we have created a method which returns a ModelAndView object and is mapped to a GET request thus any URL call ending with “test” would be routed by the DispatcherServlet to the getTestData method in the TestController.


And of course we’re returning the ModelAndView object with some model data for good measure.


The view object has a name set to “welcome“. As discussed above, the View Resolver will search for a page in the WEB-INF folder called “welcome.jsp“.


Below you can see the result of an example GET operation:



Note that the URL ends with “test”. The pattern of the URL is “/test/test“.


The first “/test” comes from the Servlet, and the second one comes from the mapping of the controller.


7. More Spring Dependencies for REST


Let’s now start looking at a RESTful controller. Of course, a good place to start is the extra Maven dependencies we need for it:



Please refer to jackson-core, spring-webmvc and spring-web links for the newest versions of those dependencies.


Jackson is of course not mandatory here, but it’s certainly a good way to enable JSON support. If you’re interested to dive deeper into that support, have a look at the message converters article here.


8. The REST Controller


The setup for a Spring RESTful application is the same as the one for the MVC application with the only difference being that there is no View Resolvers and no model map.

Spring RESTful应用程序的设置与MVC应用程序的设置相同,唯一的区别是没有View Resolversmodel map。

The API will generally simply return raw data back to the client – XML and JSON representations usually – and so the DispatcherServlet bypasses the view resolvers and returns the data right in the HTTP response body.


Let’s have a look at a simple RESTful controller implementation:


public class RestController {

    @GetMapping(value = "/student/{studentId}")
    public @ResponseBody Student getTestData(@PathVariable Integer studentId) {
        Student student = new Student();

        return student;

Note the @ResponseBody annotation on the method – which instructs Spring to bypass the view resolver and essentially write out the output directly to the body of the HTTP response.


A quick snapshot of the output is displayed below:



The above output is a result of sending the GET request to the API with the student id of 1.


One quick note here is – the @RequestMapping annotation is one of those central annotations that you’ll really have to explore in order to use to its full potential.

这里有一个简短的说明–@RequestMapping 注释是那些你必须真正探索才能充分使用其潜力的核心注释之一。

9. Spring Boot and the @RestController Annotation

9.Spring Boot和@RestController注解

The @RestController annotation from Spring Boot is basically a quick shortcut that saves us from always having to define @ResponseBody.

Spring Boot的@RestController注解基本上是一个快速捷径,使我们不必总是定义@ResponseBody

Here’s the previous example controller using this new annotation:


public class RestAnnotatedController {
    @GetMapping(value = "/annotated/student/{studentId}")
    public Student getData(@PathVariable Integer studentId) {
        Student student = new Student();

        return student;

10. Conclusion


In this guide, we explore the basics of using controllers in Spring, both from the point of view of a typical MVC application as well as a RESTful API.

在本指南中,我们将从典型的MVC应用以及RESTful API的角度,探讨Spring中使用控制器的基本知识。

Of course all the code in the article is available over on GitHub.