使用 Spring 的 REST 支援嚮應用程式新增 Atom 檢視

工程 | Alef Arendsen | 2009 年 3 月 16 日 | ...

在 Spring 3.0 中,Spring MVC 將增強 REST 支援。本文描述瞭如何使用 REST 支援在簡單示例應用程式之上實現 AtomView。按照此分步過程,瞭解使用 Spring MVC 中新的 REST 支援在簡單應用程式之上實現 AtomView 是多麼容易。

步驟 1:下載應用程式骨架

在本部落格文章的底部附近,您將找到一個簡單的下載檔案,其中包含 Web 應用程式的骨架。在其中,您將找到此應用程式所需的所有 Spring 3.0 二進位制檔案,以及 Atom 功能所需的一些額外檔案。Spring 二進位制檔案基於夜間構建,一旦 Spring 3.0 正式釋出,可能會被最終構建取代。

接下來,在 Eclipse 中載入專案,使用“匯入 > 將現有專案匯入工作區”嚮導(從“檔案”選單)。該應用程式是一個簡單的 Eclipse 動態 Web 專案,包含了 Spring MVC 設定的所有基礎架構。因此,如果您熟悉 Spring MVC,這應該不是什麼大問題。

步驟 2:審查應用程式的設定

在 /WEB-INF/web.xml 中,您將找到 Spring MVC DispatcherServlet 的定義。它從 /WEB-INF/rest-servlet.xml 檔案中載入應用程式上下文。該檔案反過來又包含一個元件掃描器,用於掃描 com.springsource.samples.rest 包中的 @Components(也包括 @Controllers)。

接下來,在 com.springsource.samples.rest 包中,您將找到一個包含兩個控制器方法的 ContentController。


@Controller
public class ContentController {
	
	private List<SampleContent> contentList = new ArrayList<SampleContent>();
	
	@RequestMapping(value="/content.*", method=RequestMethod.GET)
	public ModelAndView getContent() {
		ModelAndView mav = new ModelAndView();
		mav.setViewName("content");
		mav.addObject("sampleContentList", contentList);
		return mav;
	}
	
	@RequestMapping(value="/content.html", method=RequestMethod.POST)
	public String addContent() {
		contentList.add(SampleContent.generateContent("Alef Arendsen", new Date()));
		return "redirect:content.html";
	}
}

第一個處理器返回 SampleContent 項的列表。第二個處理器透過使用 SampleContent.generateContent() 方法新增一個新的 SampleContent 項。第一個處理器響應 GET 請求,第二個處理器響應 POST 請求。這些方法本身已使用 @RequestMapping 註解進行註釋以實現此目的。

在 rest-servlet.xml 應用程式上下文檔案中,除了元件掃描器之外,您還會找到一個 ViewResolver,在本例中是一個 InternalResourceViewResolver。它將負責檢視名稱(在 getContent() 處理器的情況下為“content”)與 JSP 頁面之間的轉換。

將其部署到例如 Tomcat 後,您應該能夠訪問 https://:8080/spring-rest/rest。這將重定向您到 /rest/content,一個由處理器捕獲的 URL。

步驟 3:實現 AtomView

為了實現 AtomView,我們將使用 Rome 專案,可從 https://rome.dev.java.net/ 獲取。在應用程式的原始設定中,檢視名稱由檢視解析器轉換為 InternalResourceView 例項,在本例中將渲染 JSP。我們將建立我們自己的 View 介面的專用例項,而不是渲染 Atom 提要。

在 com.springsource.samples.rest 包中建立一個名為 SampleContentAtomView 的類,並貼上以下程式碼。該程式碼使用了 Spring MVC 的 Atom 支援類和 Rome 專案中 Atom 提要的文件物件模型。


public class SampleContentAtomView extends AbstractAtomFeedView {

	@Override
	protected void buildFeedMetadata(Map<String, Object> model, Feed feed, HttpServletRequest request) {
		feed.setId("tag:springsource.com");
		feed.setTitle("Sample Content");
		@SuppressWarnings("unchecked")
		List<SampleContent> contentList = (List<SampleContent>)model.get("sampleContentList");
		for (SampleContent content : contentList) {
			Date date = content.getPublicationDate();
			if (feed.getUpdated() == null || date.compareTo(feed.getUpdated()) > 0) {
				feed.setUpdated(date);
			}
		}
	}

	@Override
	protected List<Entry> buildFeedEntries(Map<String, Object> model,
			HttpServletRequest request, HttpServletResponse response) throws Exception {

		@SuppressWarnings("unchecked")
		List<SampleContent> contentList = (List<SampleContent>)model.get("sampleContentList");
		List<Entry> entries = new ArrayList<Entry>(contentList.size());

		for (SampleContent content : contentList) {
			Entry entry = new Entry();
			String date = String.format("%1$tY-%1$tm-%1$td", content.getPublicationDate());
			// see http://diveintomark.org/archives/2004/05/28/howto-atom-id#other
			 entry.setId(String.format("tag:springsource.com,%s:%d", date, content.getId()));
			entry.setTitle(String.format("On %s, %s wrote", date, content.getAuthor()));
			entry.setUpdated(content.getPublicationDate());

			Content summary = new Content();
			summary.setValue(content.getText());
			entry.setSummary(summary);
			
			entries.add(entry);
		}

		return entries;

	}
}

步驟 4:設定內容協商

骨架 Web 應用程式已經提供了 HTML 檢視,現在我們也實現了生成 Atom 提要的檢視。我們需要做的最後一件事是確保 Atom 提要的請求實際上將使用 SampleContentAtomView 進行渲染,並且在請求 HTML 檢視時將渲染 JSP。

在一個完美的世界中,客戶端會使用 Accept HTTP 標頭請求其首選的特定表示。Accept HTTP 標頭(由 HTTP 規範定義)可以包含一個或多個媒體型別,並且應由瀏覽器(或任何 HTTP 客戶端)傳送,以指示其首選的表示型別。例如,Atom 提要的適當媒體型別將是“application/atom+xml”,而 HTML 檢視可能只發送“text/html”或“text/xhtml”作為 Accept 標頭。然而,這存在一個小問題。瀏覽器通常具有固定的媒體型別集,它們作為 Accept HTTP 標頭髮送,並且無法(除了使用 JavaScript)修改瀏覽器傳送的 Accept 標頭。這就是為什麼副檔名是向伺服器指示您想要哪種表示的良好替代方案。

Spring 3.0 具有 ContentNegotiatingViewResolver,它可以同時使用副檔名和 Accept 標頭。在確定了適當的媒體型別後,它會委託給一組其他檢視解析器來為我們完成此操作。以下內容需要貼上到 rest-servlet.xml 中才能使其工作。如您所見,ContentNegotiatingViewResolver 將委託給 BeanNameViewResolver(如果需要,解析為 SampleContentAtomView)或 InternalResourceViewResolver。順便說一下,下面的程式碼片段應該替換您 rest-servlet.xml 檔案中已配置的 InternalResourceViewResolver。

ContentNegotiatingViewResolver 首先檢視副檔名,然後使用 Accept 標頭(這在一定程度上是可自定義的)。我們必須將適當的副檔名對映到適當的媒體型別。在此示例中,我們將 .html 對映到媒體型別 text/html,並將 .atom 對映到 application/atom+xml。這將確保渲染適當的檢視。

如果 .atom 請求進入,ContentNegotiatingViewResolver 將查詢與 application/atom+xml 媒體型別匹配的檢視。如果 .html 請求進入,檢視解析器將查詢渲染媒體型別為 text/html 的內容的檢視。


<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
	<property name="mediaTypes">
		<map>
			<entry key="atom" value="application/atom+xml"/>
			<entry key="html" value="text/html"/>
		</map>
	</property>
	<property name="viewResolvers">
		<list>
			<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
			<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
				<property name="prefix" value="/WEB-INF/jsp/"/>
				<property name="suffix" value=".jsp"/>
			</bean>
		</list>
	</property>
</bean>

<bean id="content" class="com.springsource.samples.rest.SampleContentAtomView"/>

將其放入應用程式上下文後,重啟伺服器應該就可以解決問題。訪問 https://:8080/spring-rest/rest/content.html 檢視所有內容項並生成新的內容項。訪問 https://:8080/spring-rest/rest/content.atom 訂閱 Atom 提要。

我希望這篇小部落格文章向您展示了嚮應用程式新增 Atom 提要可以多麼簡單。除了 Atom,Spring 還具有用於渲染 PDF 和 Excel 檔案、JSON 表示和 XML 文件的檢視支援類。檢視它們並告訴我們您的想法!

下載

如所承諾的,這裡是下載。請注意,這些專案基於 Spring 的夜間構建。有關 Spring 3.0 的最新版本,請務必檢視 www.springsource.org

獲取 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助您加速進步。

瞭解更多

獲得支援

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案,只需一份簡單的訂閱。

瞭解更多

即將舉行的活動

檢視 Spring 社群所有即將舉行的活動。

檢視所有