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

Напишите первое сообщение!

Вы должны войти под своим аккаунтом чтобы оставлять комментарии