`

统一处理视图数据格式

阅读更多

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
<!--用来统一处理返回数据格式 -->   

<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">  
        <property name="favorPathExtension" value="false" /> 
        <property name="favorParameter" value="false" />  
        <property name="ignoreAcceptHeader" value="false" />  
        <property name="mediaTypes" >  
            <value> 
                atom=application/atom+xml 
                html=text/html 
                json=application/json 
                *=*/* 
            </value>  
        </property> 
    </bean>

 

 

 

第九章:对Ajax的支持——深入浅出学Spring Web MVC
浏览(23103)|评论(0)   交流分类:Java|笔记分类: SpringMVC

最直接的Ajax处理
只要在Controller的方法里面,直接使用response输出你要返回的的Ajax数据,然后return null就可以了,示例如下:
Controller示例
@RequestMapping(value = "/hello")
public ModelAndView handleRequest(UserModel um,HttpServletResponse response) throws IOException {
response.setCharacterEncoding("utf-8");
response.getWriter().println("{uuid:'"+um.getUuid()+"',name:'"+um.getName()+"'}");
return null;
}
客户端示例,使用jQuery
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<script language="javascript" src="/mvcexample/static/js/jquery-1.3.2.min.js"></script>
<script language="javascript">
$().ready(function(){
$.getJSON('/mvcexample/hello',{uuid:'1',name:'test'},function(data){
alert(data.uuid+" , "+data.name);
});
});
</script>
</html>
 
然后就可以启动服务器测试了。
数据绑定@RequestBody/@ResponseBody
@RequestBody
功能:用于将HttpServletRequest的getInputStream()内容绑定到入参
例子:
@RequestMapping(value = "/hello")
public byte[] handleRequest(@RequestBody String body)
@ResponseBody
功能:用于将方法的返回值作为响应体
例子:
@RequestMapping(value = “/hello")
@ResponseBody
public byte[] handleRequest(@RequestBody String body)
 
注意:他们都只能访问报文体,不能访问报文头
 
使用@RequestBody/@ResponseBody来支持Ajax
n可以使用@RequestBody来自动获取Ajax上传的数据
n同时也可以使用@ResponseBody,把要返回的对象自动拼成JSON的格式返回
n当然,需要加入几个jackson的包,这里加入了:
jackson-core-2.1.2.jar、jackson-annotations-2.1.2.jar、jackson-databind-2.1.2.jar
n测试使用的Controller的方法:
@RequestMapping(value = "/hello")
@ResponseBody
public UserModel handleRequest(@RequestBody String reqBody, UserModel um) {
System.out.println("the reqBody="+reqBody);
um.setName(um.getName()+",server");
return um;
}
 
n测试使用的页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<script language="javascript" src="/mvcexample/static/js/jquery-1.3.2.min.js"></script>
<script language="javascript">
$().ready(function(){
$.getJSON('/mvcexample/hello',{uuid:'1',name:'test'},function(data){
alert(data.uuid+" , "+data.name);
});
});
</script>
去测试看看吧,可以看到Controller的方法直接返回一个um对象,但是 @ResponseBody会把这个对象自动变成json格式的,再传回客户端,非常方便。
当然, @ResponseBody也支持集合对象自动变成json格式,比如:
n测试使用的Controller方法
@RequestMapping(value = "/hello")
@ResponseBody
public List<UserModel> handleRequest(@RequestBody String reqBody, UserModel um) {
System.out.println("the reqBody="+reqBody);
um.setName(um.getName()+",server");
List<UserModel> list = new ArrayList<UserModel>();
list.add(um);
UserModel um2 = new UserModel();
um2.setUuid("22");
um2.setName("222");
list.add(um2);
return list;
}
n测试使用的页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
<script language="javascript" src="/mvcexample/static/js/jquery-1.3.2.min.js"></script>
<script language="javascript">
$().ready(function(){
$.getJSON('/mvcexample/hello',{uuid:'1',name:'test'},function(data){
$.each(data,function(index,v){
alert("tr="+v.uuid+",v="+v.name);
});
});
});
</script>
 
使用HttpEntity/ResponseEntity来支持Ajax
n使用HttpEntity/ResponseEntity不但能访问到报文体,还可以访问报文头
n示例,主要的变化在Controller的方法上,页面不用变化,如下:
@RequestMapping(value = "/hello")
public ResponseEntity<List<UserModel>> handleRequest(HttpEntity<String> req, UserModel um) {
System.out.println("req headers="+req.getHeaders()+", reqBody="+req.getBody());
 
um.setName(um.getName()+",server");
List<UserModel> list = new ArrayList<UserModel>();
list.add(um);
UserModel um2 = new UserModel();
um2.setUuid("22");
um2.setName("222");
list.add(um2);
 
ResponseEntity<List<UserModel>> ret = new ResponseEntity<List<UserModel>>(list,HttpStatus.OK);
return ret;
}
对Ajax返回xml的支持
前面的Ajax使用的是json格式,下面看看对xml的支持
要让Spring Web MVC支持xml格式,需要加入如下jar包:
jaxb-api-2.2.5.jar,jaxb-impl-2.2.5.jar
在要返回的对象头上使用如下注解,例如:
@XmlRootElement(name = "testxml")
public class UserModel {
这表明返回的xml的根元素名称为testxml,注意:由于xml是单根的,所以只能返回一个对象,而不能返回一个list,如果要返回多条值,可以在这个对象中包含多个其他对象
返回的结果同样用@ResponseBody注解即可,这个注解会根据请求的类型,自动决定是返回json还是xml,当然默认是返回json格式的,如 果要返回xml格式,那么请求的时候,要指定accept=application/xml
 
示例的Controller方法
@RequestMapping(value = "/hello")
@ResponseBody
public UserModel handleRequest(HttpEntity<String> req, UserModel um) {
System.out.println("req headers="+req.getHeaders()+", reqBody="+req.getBody());
 
um.setName(um.getName()+",server");
 
PhoneNumberModel pnm = new PhoneNumberModel("123","321");
PhoneNumberModel pnm2 = new PhoneNumberModel("2222","333");
List<PhoneNumberModel> tempList = new ArrayList<PhoneNumberModel>();
tempList.add(pnm2);
tempList.add(pnm);
 
um.setPm(tempList);
 
return um;
}
 
n示例的页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
<script language="javascript" src="/mvcexample/static/js/jquery-1.3.2.min.js"></script>
<script language="javascript">
$().ready(function(){
$.ajax({
      url:'/mvcexample/hello',
      type: 'POST',
      dataType: 'xml',
      data: {uuid:'1',name:'test'},
      timeout: 1000,
      error: function(){    alert('Error loading XML document');       },
      success: function(xml){
      $(xml).find("testxml").children("pm").each(function(i){
             var uuid=$(this).children("areaCode").text();
             var name=$(this).children("phoneNumber").text();
             alert("uuid="+uuid+",name="+name);
            
      });        }    }); });
</script>
n返回的xml形如
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<testxml>
<age>0</age>
<name>test,server</name>
<pm>
<areaCode>2222</areaCode>
<phoneNumber>333</phoneNumber>
</pm>
<pm>
<areaCode>123</areaCode>
<phoneNumber>321</phoneNumber>
</pm>
<uuid>1</uuid>
</testxml>
 
HttpMessageConverter
n其实前面的程序实现对json和xml的支持,之所以能正常运行,幕后英雄就是HttpMessageConverter,它负责对http传入和传出的内容进行格式转换
n比如前面学的@RequestBody是将Http请求正文插入方法中,其实它就会使用适合的HttpMessageConverter将请求体写入某个对象
n比如前面学的@ResponseBody是将内容或对象作为Http响应正文返回,使用@ResponseBody将会跳过视图处理部分,直接调用合适的HttpMessageConverter,将返回值写入输出流
n现在只要你开启了<mvc:annotation-driven  />,它会给AnnotationMethodHandlerAdapter初始化7个转换器,可以通过调用 AnnotationMethodHandlerAdapter类的getMessageConverts()方法来获取转换器的一个集合 List<HttpMessageConverter>,默认开启的有:
ByteArrayHttpMessageConverter
StringHttpMessageConverter
ResourceHttpMessageConverter
SourceHttpMessageConverter<T>
XmlAwareFormHttpMessageConverter
Jaxb2RootElementHttpMessageConverter
MappingJacksonHttpMessageConverter
Spring是如何寻找最佳的HttpMessageConverter呢?
最基本的方式就是通过请求的accept里面的格式来匹配,如果accept=application/json之类的,就使用json的 HttpMessageConverter,如果accept=application/xml之类的,就使用xml的 HttpMessageConverter,
 
内容协商
n什么是内容协商
简单点说,就是同一资源,可以有多种表现形式,比如xml、json等,具体使用哪种表现形式,是可以协商的。
这是RESTfull的一个重要特性,Spring Web MVC也支持这个功能。
 
nSpring MVC REST是如何决定采用何种方式(视图)来展示内容呢?
一:根据Http请求的header中的Accept属性的值来判读,比如:
Accept: application/xml                将返回xml格式数据 
Accept: application/json               将返回json格式数据
 
优点:是这种方式是理想的标准方式
缺点:是由于浏览器的差异,导致发送的Accept Header头可能会不一样,从而导致服务器不知要返回什么格式的数据
 
二:根据扩展名来判断,比如:
/mvc/test.xml  将返回xml格式数据 
/mvc/test.json 将返回json格式数据 
/mvc/test.html 将返回html格式数据 
 
缺点:丧失了同一URL的多种展现方式。在实际环境中使用还是较多的,因为这种方式更符合程序员的习惯
 
三:根据参数来判断
/mvc/test?format=xml        将返回xml数据 
/mvc/test?format=json       将返回json数据 
 
缺点:需要额外的传递format参数,URL变得冗余繁琐,缺少了REST的简洁风范
n
n使用内容协商的功能,如果不使用第三种方式的话,3.2的版本可以什么都不用配置,默认就能支持前面两种。下面还是看看怎么配置,示例如下:
 
n需要在spring的配置文件中做配置,示例如下:
<!--1、检查扩展名(如my.pdf);2、检查Parameter(如my?format=pdf);3、检查Accept Header-->
    <bean id= "contentNegotiationManager" class= "org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
        <!-- 扩展名至mimeType的映射,即 /user.json => application/json -->
        <property name= "favorPathExtension" value= "true" />
        <!-- 用于开启 /userinfo/123?format=json 的支持 -->
        <property name= "favorParameter" value= "true" />
        <property name= "parameterName" value= "format"/>
        <!-- 是否忽略Accept Header -->
        <property name= "ignoreAcceptHeader" value= "false"/>
 <property name= "mediaTypes"> <!--扩展名到MIME的映射;favorPathExtension, favorParameter是true时起作用  -->
            <value>
                ccjson=application/json
                ccxml=application/xml
                html=text/html
            </value>
        </property>
        <!-- 默认的content type -->
        <property name= "defaultContentType" value= "text/html" />
    </bean>
 
<!-- ========================= VIEW定义 ========================= -->
<!-- 内容协商视图解析器;根据客户端不同的请求决定不同的view进行响应 -->
    <!-- 会自动根据解析的contentType来决定使用哪个视图解析器(默认使用整个web应用中的viewResolver) -->
    <bean class= "org.springframework.web.servlet.view.ContentNegotiatingViewResolver" p:order= "0">
        <!-- 内容协商管理器 用于决定media type -->
        <property name= "contentNegotiationManager" ref= "contentNegotiationManager"/>
        <!-- 默认视图 放在解析链最后 -->
        <property name= "defaultViews">
            <list>
           <bean class= "org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
                <bean class= "org.springframework.web.servlet.view.xml.MarshallingView">
                <property name= "marshaller"
<bean class= "org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name= "packagesToScan" value= "cn.javass"></property>
</bean>
</property>
                </bean>
            </list>
        </property>
    </bean>
 
<!-- bean name view resolver-->
    <bean class= "org.springframework.web.servlet.view.BeanNameViewResolver" p:order= "1"/>
    <!-- 默认的视图解析器 在上边的解析错误时使用 (默认使用 html)- -->
    <bean id= "defaultViewResolver" class= "org.springframework.web.servlet.view.InternalResourceViewResolver" p:order= "2">
        <property name= "viewClass" value= "org.springframework.web.servlet.view.JstlView"/>
        <property name= "contentType" value= "text/html"/>
        <property name= "prefix" value= "/WEB-INF/jsp/"/>
        <property name= "suffix" value= ".jsp"/>
    </bean>
n在mvc:annotation-driven里面配置使用内容协商
<mvc:annotation-driven
      validator= "validator"
      conversion-service= "conversionService"
      content-negotiation-manager= "contentNegotiationManager"
      >
</mvc:annotation-driven>
 
n测试文件的变化:
1:dataType: ‘json’, 这句话可以注掉了
2:在请求的url上添加 后缀,还有参数试试看,注意,前面配置的映射格式是ccjson、ccxml哦,例如:
url:'/mvcexample/hello?format=ccxml',
url:'/mvcexample/hello?format=ccjson',
url:‘/mvcexample/hello.ccxml',
url:‘/mvcexample/hello.ccjson',
 
应该可以看到根据不同的请求,服务端回返回不同格式的数据。
 
分享到:
评论

相关推荐

    数据中心建设方案(简新版).docx

    企业级ETL平台: 负责企业数据中心数据采集、加工、汇总、分发的过程,完成企业级数据标准化、集中化,实现数据脉络化、关系化,实现统一的数据处理加工,包括:非实时数据处理和实时数据处理,提供数据抽取、数据...

    Informatica MDM帮助某寿险公司建立实时、完整和准确的客户统一视图

    通过Informatica MDM,该寿险公司建立了客户统一视图,确保了数据的完整和统一。Informatica MDM提供高效查询及精准分析,帮助该公司缩短数据处理时间,节省了数据处理成本。

    数据中心建设方案.docx

    企业级ETL平台: 负责企业数据中心数据采集、加工、汇总、分发的过程,完成企业级数据标准化、集中化,实现数据脉络化、关系化,实现统一的数据处理加工,包括:非实时数据处理和实时数据处理,提供数据抽取、数据...

    数据仓库数据集市BI数据分析介绍.pptx

    数据集市:面向特定主题和部门级的数据仓库,是数据仓库的子集,数据仓库是 提供跨部门的,统一数据视图 OLAP On-Line Analytical Processing是数据仓库系统的主要应用,支持复杂的分析操作 ,侧重决策支持,并且...

    企业的数据中台的价值-光环大数据培训.zip

    在数字化转型的浪潮中,数据中台的价值体现在以下几个方面:数据整合与共享:数据中台将分散在不同业务系统中的数据进行整合,打破数据孤岛,实现数据的统一接入和共享,为企业提供全面的数据视图。数据质量管理:...

    数据中心总体架构(亚联).pptx

    动态营销支持服务 服务数 据存储 营销策略及规则中心 客户感知数据中心 价值数 据存储 即时分析服务存储 统一视图 标签库 适配库 分析数 据存储 行为轨迹处理 融合数 据存储 行为 合作伙伴 内容 客户 …… 客户标签...

    数据可视化分析.docx

    数据治理 数据治理涵盖为特定组织机构之数据创建协调一致的企业级视图(enterprise view)所需的人员、过程和技术,数据治理旨在: 1)增强决策制定过程中的一致性与信心 2)降低遭受监管罚款的风险 3)改善数据的...

    元数据驱动的大数据服务平台.docx

    元数据管理以业务模型为切入点,以数据模型(特指基于业务原始数据且未进行逻辑加工处理的模型)为中心,制定业务模型和数据模型标准,管理数据模型、数据应用、数据集成、数据处理、数据视图等对象元数据信息,监控...

    2020绿色智慧社区建设指南

    在数据资源目录下,通过对基础数据和业务数据的清理转换进行整合处理,建立多个主题数据库和数据仓库,实现全局统一的数据资源视图,并依托数据治理管控为绿色智慧社区的应用建设提供一个高质量、可靠的数据基础。...

    大数据分析应用知识培训总结大数据挖掘.pptx

    提升整个企业机构的安全:威慑需要建立有效的机制,以便企业快速检测并预测欺诈活动,同时识别和跟踪肇事者 缓冲风险&减少欺诈 对整个企业的数据进行集成和关联可以提供统一的跨不同业务线、产品和交易的欺诈视图。...

    Linux IO数据通道分享

    1.虚拟文件系统层:屏蔽下层具体文件系统操作的差异,为上层的操作提供一个统一的接口。因为有了这个层次,所以可以把设备抽象成文件,使得操作设备就像操作文件一样简单。 2.具体的文件系统层:不同的文件系统...

    大规模异构数据并行处理系统的设计、实现与实践

    设计了一种大规模异构数据并行处理系统,在统一的平台功能视图基础上,采用统一的资源管理框架,实现对结构化、JSON/XML、图数据、文档数据等多种异构数据进行存储和查询,采用统一的开发语言,实现跨数据类型和数据...

    基础地理信息数据库管理系统.doc

    导入标准入库数据(除支持自身数据格式,至少支持常规格式中MDB、SHP、E00、JP G、TIF、DEM、GRID等一种以上) 数据接边 数据入库确认 9、图形输出 点选分幅图输出 查找图幅号输出 任意区域图形输出 图形输出设置...

    多视图分类的自适应加权判别回归

    与分别处理每个视图的现有方法相比,我们提出了一种受监督的多视图特征学习框架,以统一的感知来处理各种视图。 具体来说,我们通过将原始特征的级联映射到有区别的低维子空间来融合多视图数据,在该低维子空间中,...

    毕业设计,基于SpringBoot+seajs+MySql开发的毕业设计管理系统,内含Java完整源代码,数据库脚本

    通过浏览器和服务器进行交互,浏览器对数据进行处理封装后将数据带给服务器,服务器对浏览器带来的数据进行逻辑处理,包括数据库数据的访问等等,将数据响应给浏览器,通过视图渲染呈现数据在浏览器上 本系统用户...

    毕业设计,基于springboot+mysql+bootstrap开发的毕业设计管理系统,内含源代码,数据库脚本,毕业论文

    通过浏览器和服务器进行交互,浏览器对数据进行处理封装后将数据带给服务器,服务器对浏览器带来的数据进行逻辑处理,包括数据库数据的访问等等,将数据响应给浏览器,通过视图渲染呈现数据在浏览器上 本系统用户...

    数据库基础与管理信息系统概述.doc

    文件管理阶段 20世纪60年代后期,计算机开始大量用于数据处理工作,大量的数据存储、检索和维 护成为紧迫的需求,在这一阶段有统一的软件进行数据管理,程序和数据之间有软件提 供存取方法进行转换,有共同的数据...

    全关系系统的十二条基本准则

    准则 5: 统一的数据子语言准则. 准则 6: 视图更新准则. 准则 7: 高级的插入、修改和删除操作. 准则 8: 数据物理独立性. 准则 9: 数据逻辑独立性. 准则10: 数据完整性的独立性. 准则11: 分布独立性. 准则12: ...

    大数据安全资料.docx

    虽然这些传统工具针对其特定类型的控制提供了数据视图,但这些系统的输出往往不是统一的,又或者这些数据被分解成汇总数据,并被输入到一个或者多个SIEM工具以在视觉上显示安全团队感兴趣的预定事件。一旦确定了某 ...

    sql总结.doc

    视图本身并不包含任何数据,它只包含映射到基表的一个查询语句,当基表数据发生变化,视图数据也随之变化。 (2)视图的基本写法 Create view 视图名 as select * from emp; (3)视图在哪些情况下不能被增、删、改 (1...

Global site tag (gtag.js) - Google Analytics