Spring 的 View 和 ViewResolver 都有很多实现类,支持如Json、XML、模版(Freemaker、Velocity)甚至Excel、PDF等形式的输出。
相关类在org.springframework.web.servlet.view包中。
其中有一个实现类:ContentNegotiatingViewResolver 可以根据对资源的描述来返回不同形式的视图
首先需要配置 ContentNegotiationManagerFactoryBean
在有@Confiuration注解的类中编写:
@Bean
public ContentNegotiationManagerFactoryBean contentNegotiationManagerFactoryBean(){
ContentNegotiationManagerFactoryBean bean=new ContentNegotiationManagerFactoryBean();
bean.setIgnoreAcceptHeader(true);
bean.setFavorPathExtension(false);
bean.setFavorParameter(true);
bean.setParameterName("format");
bean.setDefaultContentType(MediaType.TEXT_HTML);
Map<String,MediaType> map=new HashMap<>();
map.put("html",MediaType.TEXT_HTML);
map.put("json",MediaType.APPLICATION_JSON);
bean.addMediaTypes(map);
return bean;
}
这里的配置决定了资源的描述方式:
描述资源的三种形式
一、使用扩展名
http://localhost:8080/users.json 以json格式呈现
http://localhost:8080/users 以默认视图呈现
二、使用HTTP Header指定MIME形式
GET /users HTTP/1.1
Accept:application/json 请求时设置返回形式是json
三、使用参数
http://localhost:8080/users?format=json
扩展名形式是由setFavorPathExtension方法配置的
HTTP Header形式是由setIgnoreAcceptHeader方法配置的
参数形式是由setFavorParameter+setParameterName方法配置的
这里使用第三种配置
setDefaultContentType方法配置的是默认的MIME类型
addMediaTypes配置的是支持的MIME类型(text/html、application/json等)
然后配置 ContentNegotiatingViewResolver:
@Bean
public ContentNegotiatingViewResolver contentNegotiatingViewResolver(){
ContentNegotiatingViewResolver resolver=new ContentNegotiatingViewResolver();
resolver.setOrder(0);
resolver.setContentNegotiationManager(factoryBean().getObject());
ArrayList<View> viewList = new ArrayList<>();
View json=new MappingJackson2JsonView();
((MappingJackson2JsonView) json).setModelKey("userList");
viewList.add(json);
resolver.setDefaultViews(viewList);
return resolver;
}
这里在viewList里配置了json形式的View:MappingJackson2JsonView
userList是返回的数据的key
然后配置默认解析器:
@Bean
public BeanNameViewResolver beanNameViewResolver(){
BeanNameViewResolver resolver=new BeanNameViewResolver();
resolver.setOrder(1);
return resolver;
}
@Bean
public InternalResourceViewResolver defaultViewResolver(){
InternalResourceViewResolver viewResolver=new InternalResourceViewResolver();
viewResolver.setOrder(2);
viewResolver.setViewClass(JstlView.class);
viewResolver.setContentType("text/html");
viewResolver.setPrefix("/template/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
然后在Controller配置Handler方法:
@RequestMapping("/users")
public String listUsers(ModelMap map){
ArrayList<User> userList = new ArrayList<>();
User user1=new User("Zhangsan",27,"man");
User user2=new User("LiSi",23,"woman");
User user3=new User("Wangwu",23,"man");
userList.add(user1);
userList.add(user2);
userList.add(user3);
map.addAttribute(userList);
return "userListPage";
ModelMap用来存放模型数据,Spring在执行Handler方法之前,会先生成一个隐含的模型数据对象,把数据先存放进去,如果发现Handler的参数列表中有ModelMap、Model或Map时,就把数据传给参数(Model包含一个ModelMap对象执行数据存放,ModelMap继承LinkedHashMap实现,本质上就是用Map存放数据)
然后写一个html页面用来实现数据以text/html形式的显示
运行项目,测试结果如下: