最近工作上遇到需要快速建立 web service project 來讓同仁測試的需求,想起了好久之前看過但是一直沒試的 Spring MVC。詢問了朋友的意見與上網查了相關資料之後,發覺用這個來建還真的蠻快的,而且處理 JSON 也很方便,通通幫你整合好了,是個很好的快速解決方案,因此嘗試了一下,然後在搭配 Maven 處理 jar 檔問題,摸索加建立基礎架構大概只花兩天而已吧,整個就是迅速。以下是記錄建立整個 web service project 的過程。
Maven
上 Apache Maven Project 官網 抓 maven,設 path,然後 maven repository 設定位置如下,可用預設不用改:
/Users/mayer/Develop/apache-maven-3.3.9/conf/settings.xml
Default: ${user.home}/.m2/repository
Spring 開發工具:
- 先抓 eclipse 4.6.2 j2ee。
- 在抓 spring 開發工具 Spring Tool Suite。到 https://spring.io/tools/sts/all 抓 Update Site Archives,版本要是 4.6.2
- 開啟 eclipse,到 Help -> Install New Software,然後點 Add,在選 Archive,指到你剛剛下載的 spring 開發工具。然後選 Core Spring IDE、Extensions Spring IDE、Integrations Spring IDE、Resources Spring IDE,裝好之後會重啟,這樣 IDE 就完成了。
建立 Maven Project
建立 Maven Project
- 右鍵 New -> Maven Project,選 maven-archetype-webapp 1.0,Group Id 填 tw.com.maxkit,Artifact Id 填 ivrsample,package 會長這樣 tw.com.maxkit.ivrsample,
- 預設 index.jsp 會出錯,把 Server Runtime 加進 project 去就好。
修改 pom 檔案,加上會用到的 spring mvc dependency
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.5.RELEASE</version> </dependency>
修改 pom 在 build 內加上 plugins,確保下次執行 Maven Update Project 時 eclipse 設定不會跑掉:
<build> <finalName>ivrsample</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
Spring MVC 相關設定
在 web.xml 加上:
<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
增加 dispatcher-servlet.xml,把它放到路徑 ivrsample/WebContent/WEB-INF 底下。專案點右鍵 -> New -> Spring Bean Configuration File,名稱為 dispatcher-servlet.xml,xsd 選 mvc、p、context。然後加上這兩行:
<context:component-scan base-package="tw.com.maxkit.ivrsample.controller"/> <mvc:annotation-driven />
這樣就可以開始寫 web service,到 tw.com.maxkit.ivrsample.controller 底下建立 FooController.java,範例如下:
@Controller @RequestMapping("/foo") public class FooController { @ResponseBody @PostMapping("/test") public String hello(){ System.out.println("into test"); return "hello"; } @ResponseBody @PostMapping(path = "/testjson", consumes = "application/json") public TestBean json(@RequestBody TestBean testBean) { System.out.println("testBean = " + testBean); System.out.println(testBean.getId()); System.out.println(testBean.getName()); System.out.println(testBean.getDate()); TestBean testBean2 = new TestBean(); testBean2.setId(2); testBean2.setName("james"); testBean2.setDate(new Date()); return testBean2; } }
這個 class 的存取路徑會是:
http://localhost:8080/ivrsample/foo
有開放兩個 api:
http://localhost:8080/ivrsample/foo/test http://localhost:8080/ivrsample/foo/testjson
json 處理參考接下來的說明。
Spring MVC with Json
需要 jackson lib,在 pom 加上:
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>
然後你的 controller method 直接回傳物件就好,沒有其他設定了,如下:
@ResponseBody
@PostMapping(path = "/testjson", consumes = "application/json")
public TestBean json(@RequestBody TestBean testBean) {
System.out.println("testBean = " + testBean);
System.out.println(testBean.getId());
System.out.println(testBean.getName());
System.out.println(testBean.getDate());
TestBean testBean2 = new TestBean();
testBean2.setId(2);
testBean2.setName("james");
testBean2.setDate(new Date());
return testBean2;
}
遇到日期時,他會回傳 timestamp,若要日期轉字串則要加上:
public class TestBean {
private int id;
private String name;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date date;
// ... get and set method
}
日期相關處理參考:http://wiki.fasterxml.com/JacksonFAQDateHandling
不讓 null 回傳,在 bean 上面加上:
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
@JsonInclude(Include.NON_NULL)
public class ApiOut { ... }
or
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
public class ApiOut { ... }
null 回傳處理參考:http://stackoverflow.com/questions/11757487/how-to-tell-jackson-to-ignore-a-field-during-serialization-if-its-value-is-null
取 ServletContext
在你的 Spring 控管 object 內寫上這個,就會自動注入了
protected ServletContext context;
@Autowired
public void setContext(ServletContext context) {
this.context = context;
}
另一種方式,連 get、set 都省了,上網查是用 JAVA Reflection 做到的,不過細節沒去看就是了:
@Autowired
protected ServletContext context;
沒有留言:
張貼留言