SpringMVC 多视图解析

虽然SpringMVC技术已经很成熟了,视图渲染技术相信大神们都熟透了,因为项目中使用到了多视图渲染,因此在这里记录一下。欢迎大家批评指点。

SpringMVC的视图和视图解析器实现了MVC的充分解耦,使得采用哪种视图对象对模型数据渲染的工作,不需要处理器去操心。

首先说下视图:其作用是讲模型数据以某种形式呈现给用户。(text/html、json、xml等)。Spring为我们实现了高度抽象接口 org.springframework.web.servlet包中的View接口,该接口中有两个方法:

  1. String getContentType(): 视图对应的MIME 类型,如text/html、json、xml等 。数据渲染成哪种类型
  2. void render(Map model,HttpServletRequest request,HttpServletResponse response); 渲染数据

不同类型的视图实现对应不同View实现类。这里不多说了。

然后是视图解析器:Spring MVC为逻辑视图名的解析提供了不同的解析策略,可以在Spring WEB 上下文中配置(这里我定义的名称为:dispatcher-servlet.xml)一种或者多种解析策略,并指定他们的先后顺序。所有视图解析器都实现ViewResolver接口。

因为要多视图解析,这里就只说一下多视图解析器 ContentNegotiatingViewResolver,也被成为内容协商解析器。该解析是在Spring 3.0新增的,它不负责具体的视图解析,而是作为一个中间角色,根据请求的MIME类型,从ApplicationContext中选择一个适合的视图解析器去做视图解析的工作。

通过下面的实例详细说明,

例如项目中使用到REST风格的URL以不同的MIME类型获取相同的资源。

  1. /spring-web/jsonfeed  默认访问方式,返回text/html
  2. spring-web/jsonfeed?content=json 返回json格式的数据
代码清单:在dispatcher-servlet.xml中,添加ContentNegotiatingViewResolver
<span style="color:#009900;"><!-- 根据客户端不同的请求,决定不同的view进行响应 --></span>
	<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
		<span style="color:#33cc00;"><!-- 该视图解析器启动顺序设置为最高 --></span>
		<property name="order" value="0"/>
		<property name="defaultContentType" value="text/html"></property>
		<span style="color:#009900;"><!-- 因为不同浏览器产生的AcceptHeader不同,所以不采用Accept确定MIME类型,忽略对Accept Header的支持 --></span>
		<property name="ignoreAcceptHeader" value="true" />
		<span style="color:#009900;"><!-- 取消根据URL扩展名确认MIMEtype的方式  ex:aa.json --></span>
		<property name="favorPathExtension" value="false"/>
		<span style="color:#009900;"><!-- 通过参数content,确定MIME type ,ex: xx/aa.html?content=json --></span>
		<property name="favorParameter" value="true" />
		<property name="parameterName" value="content"/>
		<span style="background-color: rgb(255, 255, 255);"><span style="color:#009900;"><!--根据请求参数值和MIME类型的映射列表 --></span></span>
		<property name="mediaTypes">
			<map>
				<entry key="html" value="text/html" />
				<entry key="json" value="application/json" />
			</map>
		</property>
		<property name="defaultViews">
			<list>
				<span style="color:#009900;"><!--for application/json  --></span>
				<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
			</list>
		</property>
	</bean>
以上方式便实现了多视图解析功能,但是一般ApplicationContext中需要有默认的视图解析,来支持默认的text/html类型请求的解析,以下系统默认支持的配置。
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
		<property name="order" value="10"/>
	</bean>
	<span style="color:#009900;"><!-- URL中不带参数content,由于通过defaultContentType="text/html"指定了默认的MIME类型,因此使用该解析 --></span>
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="order" value="20"/>
		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/views" />
		<property name="suffix" value=".jsp"></property>
	</bean>

 到此为止,应用上下文中的多视图支持配置完成,在Controller中实现一个restful 接口。

     

@RequestMapping(value="jsonfeed")
	@ResponseBody
	public  Object getJson(Model model){
		List<TournameContent> tournameCountList = new ArrayList<TournameContent>();
		tournameCountList.add(TournameContent.generateContent("test", new Date(), "wo", "http:123.com"));
		tournameCountList.add(TournameContent.generateContent("www", new Date(), "www", "http:www.com"));
		tournameCountList.add(TournameContent.generateContent("rrr", new Date(), "rrr", "http:rrr.com"));
		model.addAttribute("items", tournameCountList);
		model.addAttribute("status", 0);
		return model;
	}
然后我们通过spring-test做一下单元测试,通过post方式执行HTTP请求,查看一下返回数据。

@ContextConfiguration(locations={"dispatcher-servlet.xml"})
public class SpringTest extends AbstractTestNGSpringContextTests {
	
	@Test
	public void post(){
		String url = "http://127.0.0.1:18080/spring-web/jsonfeed?content=json";
		HttpClient client = new DefaultHttpClient();
		HttpPost httpPost = new HttpPost(url);
		StringBuffer sb = new StringBuffer();
		InputStream is = null;
		try {
			HttpResponse response = client.execute(httpPost);
			System.out.println("响应状态码"+response.getStatusLine().getStatusCode());
			is= response.getEntity().getContent();
			
			BufferedReader reader = new BufferedReader(new InputStreamReader(is));
			String line = null;
			while((line=reader.readLine())!=null){
				sb.append(line);
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		System.out.println(sb.toString());
	}
}
该测试类的以TESTNG方式运行,控制台输出结果为:

响应状态码200
{"items":[{"author":"test","publicationDate":1421125676544,"name":"wo","link":"http:123.com","id":0},{"author":"www","publicationDate":1421125676544,"name":"www","link":"http:www.com","id":0},{"author":"rrr","publicationDate":1421125676544,"name":"rrr","link":"http:rrr.com","id":0}],"status":0}
PASSED: post

json方式输出成功,然后测试默认方式,直接在浏览器中执行 http://127.0.0.1:18080/spring-web/jsonfeed,浏览器会加载jsonfeed.jsp。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值