Spring4 MVC REST服務使用@RestController實例

在這篇文章中,我們將通過開發使用 Spring4 @RestController 註解來開發基於Spring MVC4的REST風格的JSON服務。我們將擴展這個例子通過簡單的註釋與JAXB標註域類支持XML輸出和JSON輸出。在這個示例中,我們需要URL的後綴爲 .xml 或 .json 以獲得所需的輸出。

使用以下技術:

  • Spring 4.0.6.RELEASE
  • jackson-mapper-asl 1.9.13
  • Maven 3
  • JDK 1.6
  • Tomcat 7.0.54
  • Eclipse JUNO Service Release 2

讓我們現在開始!

第1步:創建目錄結構

之前的文章 使用Eclipse創建Maven Web項目包含了一步一步的指導,使用 Eclipse 來創建一個Maven項目(Spring4MVCRestServiceDemo)。

下面是最終的項目目錄結構:

Spring4

我們將使用 Spring Java配置而不使用XML。現在,讓我們來添加/更新上述項目結構中提到的內容。

第2步:使用 pom.xml 更新所需的依賴


<?xml version="1.0"?>
<project
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
    xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.yiibai.springmvc</groupId>
    <artifactId>Spring4MVCRestServiceDemo</artifactId>
    <packaging>war</packaging>
    <version>1.0.0</version>
    <name>Spring4MVCRestServiceDemo Maven Webapp</name>

    <properties>
        <springframework.version>4.0.6.RELEASE</springframework.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
    </dependencies>
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>2.4</version>
                    <configuration>
                        <warSourceDirectory>src/main/webapp</warSourceDirectory>
                        <warName>Spring4MVCRestServiceDemo</warName>
                        <failOnMissingWebXml>false</failOnMissingWebXml>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
        <finalName>Spring4MVCRestServiceDemo</finalName>
    </build>
</project> 

上面的 pom.xml 與以前的教程中定義的相同。有一個顯着的區別: 我們已經包括一個依賴於Jackson 庫(jackson-mapper-asl),其將用於所述響應數據轉換成JSON字符串。

對於Spring 4.1.x 和以上, jackson-databind 2.3或以上是推薦使用的,以避免轉換問題。

安全的選擇,你可以包括 jackson-databind 最新版本。

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.5.3</version>
    </dependency>

第3步:添加一個POJO/域對象

package com.yiibai.springmvc.domain;

public class Message {

    String name;
    String text;

    public Message(String name, String text) {
        this.name = name;
        this.text = text;
    }

    public String getName() {
        return name;
    }

    public String getText() {
        return text;
    }

}

上述對象將從控制器返回 Jackson 轉換成 JSON 的格式。

第4步:添加控制器

在 src/main/java 包下添加控制器類,如下圖所示。


package com.yiibai.springmvc.controller;

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

import com.yiibai.springmvc.domain.Message;

@RestController
public class HelloWorldRestController {

    @RequestMapping("/hello/{player}")
    public Message message(@PathVariable String player) {

        Message msg = new Message(player, "Hello " + player);
        return msg;
    }

} 

@PathVariable表示參數將被綁定到變量 URI 模板。更有趣的事情,這裏要注意的是,這裏我們使用的是 @RestController 註解,這標誌着這個類作爲控制器,每一個方法返回域對象/pojo代替一個視圖。這意味着我們不再使用視圖解析器,我們不再直接發送響應的HTML,我們只發送的域對象轉換成格式。在我們的例子中,由於 jackson 包含在類路徑中,消息對象將轉換成JSON格式。

第5步:添加配置類


package com.yiibai.springmvc.configuration;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.yiibai.springmvc")
public class HelloWorldConfiguration {

} 

在這裏,這個類是主要提供組件,掃描和註釋支持。需要注意的是,我們沒有任何視圖解析器配置,因爲我們在Rest案例並不需要。

第6步:添加初始化類

添加一個初始化類實現WebApplicationInitializer在src/main/java,使用如下圖所示指定包(在這種情況下,替代在web.xml中定義的任何spring的配置)。在Servlet 3.0容器啓動時,這個類會被加載並實例,它是在啓動時方法將通過servlet容器調用。


package com.yiibai.springmvc.configuration;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

public class HelloWorldInitializer implements WebApplicationInitializer {

    public void onStartup(ServletContext container) throws ServletException {

        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(HelloWorldConfiguration.class);
        ctx.setServletContext(container);

        ServletRegistration.Dynamic servlet = container.addServlet(
                "dispatcher", new DispatcherServlet(ctx));

        servlet.setLoadOnStartup(1);
        servlet.addMapping("/");
    }

} 

更新:請注意,上面的類可以寫成更加簡潔[和它的首選方式],通過擴展 AbstractAnnotationConfigDispatcherServletInitializer 基類,如下所示:


package com.yiibai.springmvc.configuration;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class HelloWorldInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>\[\] getRootConfigClasses() {
        return new Class\[\] { HelloWorldConfiguration.class };
    }

    @Override
    protected Class<?>\[\] getServletConfigClasses() {
        return null;
    }

    @Override
    protected String\[\] getServletMappings() {
        return new String\[\] { "/" };
    }

}

第7步:構建和部署應用程序

現在構建 war(在 Eclipse中)或通過 Maven 命令行( mvn clean install)。 部署 war 文件到Servlet3.0容器。

運行它。訪問:  http://localhost:8080/Spring4MVCRestServiceDemo/hello/Messi ,您將看到 JSON 輸出,如下圖所示:

Spring4

Spring4

就這樣,所有輸出如上所示。

適應XML輸出

現在,如上面提到的,只是通過增加模型類(Message)JAXB註釋,我們可以讓XML輸出支持以及JSON輸出。下面是相同的演示:


package com.yiibai.springmvc.domain;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "pizza")
public class Message {

    String name;
    String text;

    public Message(){

    }

    public Message(String name, String text) {
        this.name = name;
        this.text = text;
    }

    @XmlElement
    public String getName() {
        return name;
    }

    @XmlElement
    public String getText() {
        return text;
    }

}

編譯,部署並再次運行它,會看到下面的輸出(注意URL後綴),訪問URL: http://localhost:8080/Spring4MVCRestServiceDemo/hello/Yiibai.xml

Spring4

再次訪問:http://localhost:8080/Spring4MVCRestServiceDemo/hello/Yiibai.json

Spring4

如果沒有任何後綴,默認格式是XML:

Spring4

到這裏,全部完成!
代碼下載:http://pan.baidu.com/s/1pK1K2BD