Spring MVC і кілька ViewResolver

квітня
28
2012

В Spring MVC є можливість створювати ланцюжки об'єктів ViewResolver. Таким чином, обробка різних запитів може здійснюватись різними ViewResolver'амі і, відповідно, повертається результат може бути абсолютно різним.

Розглянемо наступний завдання: необхідно щоб на всі запити від клієнта поверталась відповідь у вигляді HTML-сторінки, крім одного запиту /plaintext-view - відповідь на нього має бути звичайним текстом без заголовків, які притаманні HTML-сторінкам.

Вирішимо цю задачу, скориставшись різними стандартними ViewResolver'амі: InternalResourceViewResolver (для HTML-сторінок) і XmlViewResolver (для тексту).

Для початку необхідно змінити конфігурацію контексту сервлету. Додайте наступні ViewResolver'и в файл конфігурації:


<beans:bean class="org.springframework.web.servlet.view.XmlViewResolver">
	<beans:property name="order" value="1" />
	<beans:property name="location" value="/WEB-INF/views.xml" />
</beans:bean>

<beans:bean
	class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<beans:property name="viewClass"
		value="org.springframework.web.servlet.view.JstlView" />
	<beans:property name="order" value="2" />
	<beans:property name="prefix" value="/WEB-INF/views/" />
	<beans:property name="suffix" value=".jsp" />
</beans:bean>

Зверніть увагу на властивість order. Завдяки йому XmlViewResolver буде виконуватися першим, потім - InternalResourceViewResolver. Якщо і в InternalResourceViewResolver запит не буде опрацьовано, то згенерує виняток ServletException.

Увага! InternalResourceViewResolver повинен виконуватися ЗАВЖДИ в останню чергу. Інакше це привидітися до помилок.

Повний файл конфігурації контексту сервлета виглядає наступним чином:


<?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.0.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing 
		infrastructure -->

	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving 
		up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<beans:bean class="org.springframework.web.servlet.view.XmlViewResolver">
		<beans:property name="order" value="1" />
		<beans:property name="location" value="/WEB-INF/views.xml" />
	</beans:bean>

	<beans:bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="viewClass"
			value="org.springframework.web.servlet.view.JstlView" />
		<beans:property name="order" value="2" />
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>

	<context:component-scan base-package="com.seostella.spring" />

</beans:beans>

XmlViewResolver у властивості location повідомляє розташування конфігураційного файлу. У нашому випадку - /WEB-INF/views.xml:


<?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.0.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
		
	<beans:bean name="plainTextView" class="com.seostella.spring.PlainTextView" />
</beans:beans>

У нашому прикладі тільки один bean під ім'ям plainTextView. Насправді їх може бути як завгодно багато. Зверніть увагу, що ім'я буде використовуватися контролером в якості імені уявлення.

Відображення виглядає наступним чином:


package com.seostella.spring;

import java.io.PrintWriter;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.view.AbstractView;

public class PlainTextView extends AbstractView{
	@Override
	protected void renderMergedOutputModel(Map<String, Object> model,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		
	    PrintWriter writer = response.getWriter();
	    writer.write("Hi from PlainTextView");
	    writer.close();
		
	}
}

Як видно, в потік відповіді записується звичайний текст "Hi from PlainTextView".

І, нарешті, контролер виглядає так:


@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
	return "home";
}

@RequestMapping(value = "/plaintext-view", method = RequestMethod.GET)
public String customView() {
	return "plainTextView";
}

Якщо ім'я відображення, яке повертає контролер, збігається з одним із bean'ов в файлі /WEB-INF/views.xml, то буде використовуватися XmlViewResolver, в іншому випадку - InternalResourceViewResolver. Тобто, в цьому прикладі для методу home використовується InternalResourceViewResolver, а для методу customView - XmlViewResolver.

Завантажити код проекту, що демонструє роботу ланцюжка об'єктів ViewResolver, Ви можете за наступним посиланням - Завантажити spring-viewresolver.zip

Напишіть перше повідомлення!

Ви повинні увійти під своїм аккаунтом щоб залишати коментарі