转自:http://cnge06.iteye.com/blog/1755856
Spring MVC REST内容协商(同一资源,多种展现方式,html、xml、json等,通过ContentNegotiatingViewResolver)
突然对ruby on rails来了兴趣,便捣弄了两天,用脚手架做了个hello world,实质上也就是一行命令的事,的确够效率。看一下Controller,其REST风格实在太简洁了。
- # GET /posts
- # GET /posts.json
- def index
- @posts = Post.all
- respond_to do |format|
- format.html # index.html.erb
- format.json { render json: @posts }
- end
- end
一直在关注着spring,如今一般的web项目,从前到后几乎可以用spring直接搞定了。因此,对spring mvc及REST相关内容自然也有所了解。
于是今天就在想,spring mvc应该也可以对同一资源,实现多种展现才是,前提当然是在同一个方法里。(之前是为json的处理单独写一个Controller的method的,倒也没什么问题。)
就如以下:
- @RequestMapping(value={"/user/{id}","/user/{id}.json"})
- public ModelAndView show(@PathVariable(value="id")String id){
- User user=userService.get(Long.valueOf(id));
- ModelAndView mav=new ModelAndView("show");
- mav.addObject(user);
- return mav;
- }
当我请求/user/1时,便会回应show的视图,当我请求/user/{id}.json时,便会回应json格式的数据。
而spring mvc中ContentNegotiatingViewResolver便能满足这个需求,除了json,还有xml/rss。
相关资讯可查看这里(里面还对RESTful中同一资源多种表述进行描述的三种方式进行了讨论。)。
我当前使用spring版本是3.2,在这个版本里,对ContentNegotiatingViewResolver作了修改,原样参照以上链接配置,出现java.lang.ClassCastException: java.lang.String cannot be cast to org.springframework.http.MediaType 的异常。版本原因造成这个问题。
在springsource的论坛里有人询问和解答,请看这里或者这里。
起作用的配置,例:
- <!-- REST -->
- <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
- <property name="order" value="1" />
- <property name="contentNegotiationManager">
- <bean class="org.springframework.web.accept.ContentNegotiationManager">
- <constructor-arg>
- <bean class="org.springframework.web.accept.PathExtensionContentNegotiationStrategy">
- <constructor-arg>
- <map>
- <entry key="json" value="application/json"/>
- <entry key="xml" value="application/xml"/>
- </map>
- </constructor-arg>
- </bean>
- </constructor-arg>
- </bean>
- </property>
- <property name="defaultViews">
- <list>
- <!-- JSON View -->
- <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
- <!-- XML View -->
- <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
- <constructor-arg>
- <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
- <property name="packagesToScan">
- <list>
- <value>documentLoader.domain</value>
- </list>
- </property>
- </bean>
- </constructor-arg>
- </bean>
- </list>
- </property>
- </bean>
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
- <property name="prefix" value="/WEB-INF/views/" />
- <property name="suffix" value=".jsp" />
- </bean>
- 仅作小记,如果刚好对他人有用就更好了。