使用 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 Dynamic Web Project,已設定 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://127.0.0.1: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 媒體類型相符的視圖。視圖解析器將尋找視圖,以呈現媒體類型為 text/html 的內容,如果收到 .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://127.0.0.1:8080/spring-rest/rest/content.html 以檢視所有內容項目並產生新的項目。前往 https://127.0.0.1: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 社群中所有即將到來的活動。

檢視全部