Announcement Announcement Module
Collapse
No announcement yet.
Content negotiation - STS Media example Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Content negotiation - STS Media example

    Hi all,

    I am currently working through the Spring Finance Manager example as created by Stefan of the Spring team.

    Tutorial located at:

    http://stsmedia.net/series/spring-finance/

    Towards the end of Stefans tutorial he introduces a useful way of performing content negotiation like so:

    Code:
    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver" p:order="1">
    		<property name="mediaTypes">
    			<map>
    				<entry key="xml" value="application/xml"/>
    				<entry key="json" value="application/json"/>
    			</map>
    		</property>
    		<property name="defaultViews">
    			<list>
    				<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
    					<property name="marshaller">
    						<bean class="org.springframework.oxm.xstream.XStreamMarshaller" p:autodetectAnnotations="true" />
    					</property>
    				</bean>
    				<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
    			</list>
    		</property>
    	</bean>
    
    	<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" p:order="2"/>
    As my application uses Tiles I have slightly modified this to be:

    (Might be useful for readers)

    Code:
    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver" p:order="1">
    		<property name="mediaTypes">
    			<map>
    				<entry key="xml" value="application/xml"/>
    			</map>
    		</property>
    		<property name="defaultViews">
    			<list>
    				<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
    					<property name="marshaller">
    						<bean class="org.springframework.oxm.xstream.XStreamMarshaller" p:autodetectAnnotations="true" />
    					</property>
    				</bean>
    			</list>
    		</property>
    	</bean>
    
    	<bean id="viewResolver" class="org.springframework.js.ajax.AjaxUrlBasedViewResolver" p:order="2" >
    		<!-- <property name="viewClass" value="org.springframework.webflow.mvc.view.FlowAjaxTilesView"/>  -->
    		<property name="viewClass" value="my.spring.view.AjaxTiles21View"/>
    	</bean>
    However I have noticed that with both mine and Stefan's example that if you want to invoke the normal Web view you have to add .html to your urls.

    So if you visit http://localhost:8080/FinanceManager/person.xml or http://localhost:8080/FinanceManager/person they both render the XML views - however if you were to visit http://localhost:8080/FinanceManager/person.html you would see the normal JSP view.

    Other than UrlRewriting is there anyway to avoid this as I would like people to simply be able to go to http://localhost:8080/FinanceManager/person to see web views.

    As a side note I have been testing this using the Google Chrome browser in case that makes any odds such as the accept header being different?

    Eggsy

  • #2
    Further info

    Hi all,

    To add further information to this I have just tested the above issue with Firefox (version 3.5.7 on Ubuntu) and when visiting http://localhost:8080/FinanceManager/person on Firefox the correct (web) view is chosen.

    Is something incorrect in my setup or is it within the org.springframework.web.servlet.view.ContentNegoti atingViewResolver?


    Eggsy

    Comment


    • #3
      Solved

      Hi all,

      I have managed to find out how to solve this issue. You basically have to set two properties on the ContentNegotiatingResolver. They are the defaultContentType and the ignoreAcceptHeader.

      Please see my example below:

      Code:
      <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver" p:order="1">
      		<property name="mediaTypes">
      			<map>
      				<entry key="xml" value="application/xml"/>
      				<entry key="html" value="text/html"/>
      			</map>
      		</property>
      		<property name="defaultViews">
      			<list>
      				<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
      					<property name="marshaller" ref="xstreamMarshaller" />
      				</bean>
      			</list>
      		</property>
      		<property name="defaultContentType" ref="htmlMediaType" />
      		<property name="ignoreAcceptHeader" value="true" />
      	</bean>
      	
      	<bean id="htmlMediaType" class="org.springframework.http.MediaType">
      		<constructor-arg value="text/html" />
      	</bean>
      This way in someone visits the URL without using the .html extension it defaults to the HTML view.

      Hope this helps someone.

      Comment


      • #4
        How does controller method look?

        What gets returned? ModelAndView? Does its derivation (TilesModelAndView, XMLModelAndView, etc) have to correspond to the extension?

        Comment

        Working...
        X