2013年11月7日 星期四

Spring MVC Restful JSON and XML

從Spring MVC 3.1開始,設定純Json或XML的response變得很簡單了。
  1. 以下是Maven pom file該加入的dependency
    (這是指選完Spring MVC template後,該額外加入的library)。
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-oxm</artifactId>
        <version>${org.springframework-version}</version>
    </dependency>
    
    <!-- Jackson -->
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-core-asl</artifactId>
        <version>1.9.12</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.12</version>
    </dependency>
    
    <!-- marshaling and unmarshaling of XML data -->
    <dependency>
        <groupId>org.codehaus.castor</groupId>
        <artifactId>castor-xml</artifactId>
        <version>1.3.2</version>
    </dependency>
    

  2. 在Controller的method上加入@responsebody,並且把return type改成自已要的。

        @RequestMapping(value="/", method = RequestMethod.GET)
    @ResponseBody
    public Posts getAll() {     
        
        List posts = new ArrayList();
        
        Post p1 = new Post();
        p1.setId(1);
        p1.setValue(11);
        
        Post p2 = new Post();
        p2.setId(2);
        p2.setValue(22);
        
        posts.add(p1);
        posts.add(p2);
        
        Posts ps = new Posts();
        ps.setPosts(posts);
    
        return ps;
    }
    

    以下是Post POJO的內容。
    加上@XmlRootElement(name = "post")的用意是讓Spring MVC也能回應XML,而JSON是什麼都不用加即可運作。
    Mark掉的@XmlElement是讓你選擇要的property,如果都不加,預設是全部使用;一加上去後,就只會認有mark這個annotation的property。
    @XmlRootElement(name = "post")
    public class Post {
    //  @XmlElement
        private int id;
    //  @XmlElement
        private int value;
        
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public int getValue() {
            return value;
        }
        public void setValue(int value) {
            this.value = value;
        }
        
        @Override
        public String toString() {
            return "Post [id=" + id + ", value=" + value + "]";
        }
    }
    
    

    當我們需要傳List的時候,也可以把它封裝在POJO裡,這樣遇見的問題會比較少。
    @XmlRootElement(name = "posts")
    public class Posts {
        private List posts;
        
        public List getPosts() {
            return posts;
        }
    //  @XmlElement
        public void setPosts(List posts) {
            this.posts = posts;
        }
        
        @Override
        public String toString() {
            return "Posts [posts=" + posts + "]";
        }
    }
    
    
  3. 因為我從頭到尾都是用annotation來設定,因此如果你是從XML based的環境上來的,記得在servlet-context.html上加入一些內容。
    
    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/mvc"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:beans="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
    
        <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
        
        <!-- Enables the Spring MVC @Controller programming model -->
        <annotation-driven/>
        
        <context:component-scan base-package="com.test.restful.web" />
    </beans:beans>
    
其實3.1版的環境就真的這麼簡單就好了.....

另外說明一下,上述的code已經足以啟動XML或JSON的回傳內容。
基本上它會回傳哪一種格式,完全看Request Header的屬性"Accept"決定。
如果是"application/json"則回傳JSON格式,反之"application/xml"則回傳XML格式。
若同時出現,則看哪一個比較前面,便會以那個為預設值。

Reference: http://www.mkyong.com/spring-mvc/spring-3-mvc-and-xml-example/

沒有留言:

張貼留言