在Spring-MVC控制器中支持多种内容类型

问题描述:

Rails控制器使得支持多种内容类型变得非常简单。在Spring-MVC控制器中支持多种内容类型

respond_to do |format| 
    format.js { render :json => @obj } 
    format.xml 
    format.html 
end 

美丽。在一个控制器动作中,我可以轻松响应多种内容类型,并且具有足够的灵活性,可以显示我想要呈现的内容,可以是模板,也可以是我的对象的序列化表单等。

我可以做类似于Spring的MVC?在Spring中支持多种内容类型的标准是什么?我见过涉及视图解析器的解决方案,但这看起来难以管理,特别是如果我想支持除xhtml和xml之外的JSON。

任何建议表示赞赏,但更简单,更优雅的解决方案可以理解的多;)

编辑

如果我断言,视图解析器是难以管理是不正确,请随时纠正我,并提供一个例子。最好能够返回xml,xhtml和JSON。

在Spring 3中,您想使用org.springframework.web.servlet.view.ContentNegotiatingViewResolver

它需要一个媒体类型列表和ViewResolvers。从Spring docs

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> 
    <property name="mediaTypes"> 
    <map> 
     <entry key="atom" value="application/atom+xml"/> 
     <entry key="html" value="text/html"/> 
     <entry key="json" value="application/json"/> 
    </map> 
    </property> 
    <property name="viewResolvers"> 
    <list> 
     <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
     <property name="prefix" value="/WEB-INF/jsp/"/> 
     <property name="suffix" value=".jsp"/> 
     </bean> 
    </list> 
    </property> 
    <property name="defaultViews"> 
    <list> 
     <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" /> 
    </list> 
    </property> 
</bean> 
<bean id="content" class="com.springsource.samples.rest.SampleContentAtomView"/> 

控制器:

import org.springframework.stereotype.Controller; 
import org.springframework.ui.ModelMap; 
import org.springframework.web.bind.annotation.RequestMapping; 

@Controller 
public class BlogsController { 

    @RequestMapping("/blogs") 
    public String index(ModelMap model) { 
     model.addAttribute("blog", new Blog("foobar")); 
     return "blogs/index"; 
    }  
} 

您还需要包括杰克逊JSON罐子。

+1

就像Rails一样容易和“美丽”?不,但是按照Java标准,可能和我们一样好。 – Todd 2010-12-10 02:13:41

这里是工作示例控制器,它根据请求头“Content-Type”呈现JSON和HTML。

import org.springframework.http.HttpStatus; 
import org.springframework.http.ResponseEntity; 
import org.springframework.util.MimeTypeUtils; 
import org.springframework.web.bind.annotation.PathVariable; 
import org.springframework.web.bind.annotation.RequestHeader; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RequestParam; 
import org.springframework.web.bind.annotation.RestController; 

@RestController 
public class PersonService { 
    @RequestMapping(value = "/persons/{userId}", method = RequestMethod.GET) 
    public ResponseEntity<?> getPersonByName(@RequestHeader("Content-Type") String contentMediaType, 
      @PathVariable("userId") String userId,@RequestParam("anyParam") boolean isAscending) throws IOException { 

     Person person = getPersonById(userId); 
     if (isJSON(contentMediaType)) { 
      return new ResponseEntity<Person>(person, HttpStatus.OK); 
     } 

     return new ResponseEntity("Your HTML Goes Here", HttpStatus.OK); 
     //Note: Above you could use any HTML builder framework, like HandleBar/Moustache/JSP/Plain HTML Template etc. 
    } 


    private static final boolean isJSON(String contentMediaType) { 
     if ("application/json".equalsIgnoreCase(contentMediaType)) { 
      return true; 
     } 

     return false; 
    } 

}