当前位置: 首页 > 后端技术 > Node.js

SpringBoot系列教程定义接口返回类型的几种方法

时间:2023-04-03 15:52:54 Node.js

SpringBoot系列教程:定义接口返回类型的几种方式实现一个web接口返回json数据,基本上是每个javaer都非常熟悉的;那么问题来了,如果我有一个接口,除了想返回json格式的数据之外,返回xml格式的数据是否可行?答案当然是可行的。下面介绍如何处理接口的返回数据类型。一、项目搭建本文创建的示例项目使用SpringBoot2.2.1.RELEASE+maven3.5.3+idea1开发,pom依赖于具体的SpringBoot项目创建,不再赘述。对于pom文件,需要重点关注以下两个依赖类>com.fasterxml.jackson.dataformatjackson-dataformat-xml注意jackson-datafromat-xml这个依赖,加上这个是主要是支持返回xml格式的数据二.多种设置返回类型的方式通常来说,RestController接口默认返回Json格式的数据。当我们引入上面的xml包之后会发生什么?还是json?1.通过produce设置返回类型如果一个接口要返回json或者xml格式的数据,最简单的想到的方法就是直接在RequestMapping注解中设置produce属性。该值主要用于设置该接口的响应头内容类型;比如我们现在有两个接口,一个指定返回json格式的数据,一个指定返回xml格式的数据,可以这样写:@RestControllerpublicclassIndexRest{@DatapublicstaticclassResVo{私有整数代码;私有字符串消息;私有T数据;publicResVo(intcode,Stringmsg,Tdata){this.code=code;this.msg=味精;这个。数据=数据;}}@GetMapping(path="/xml",produces={MediaType.APPLICATION_XML_VALUE})publicResVoxml(){returnnewResVo<>(0,"ok","returnxml");}@GetMapping(path="/json",produces={MediaType.APPLICATION_JSON_VALUE})publicResVojson(){returnnewResVo<>(0,"ok","returnjson");}}在上面的实现中,produces=application/xmlproduces=applicatin/json接下来我们访问看看返回是否符合预期从上面的截图我们也可以看到xml接口返回的是xml格式的数据;json接口返回json格式的数据2.上面通过请求头accept设置返回类型的方法很直观。我们自然有一个问题,当接口上没有指定produces属性时,直接访问将如何表现?@GetMapping(path="/")publicResVoindex(){returnnewResVo<>(0,"ok","simpletest");}请注意上面的截图,返回的两种访问方式数据类型不一致application/xhtml+xml那么问题来了,为什么两者的表达方式不一致呢?再看上图三秒,你会发现主要区别在于请求头Accept不同;我们可以通过这个请求头参数来请求服务器返回我想要的数据类型,比如指定返回json格式的数据curl'http://127.0.0.1:8080'-H'Accept:application/xml'-ivcurl'http://127.0.0.1:8080'-H'Accept:application/json'-iv从上面的执行结果也可以看出返回的类型和预期的一致;表示请求头可以设置多个MediaType,用英文逗号隔开,后台接口会取自己定义的produce和请求头想要的mediaType的交集,最终选择顺序为accept顺序其出现以实际表现为准以上声明。通过请求头控制返回数据类型的方法可以说是非常经典的策略。(遵循html协议还能说什么呢!)3.请求参数控制返回类型除了上面介绍的两种方式之外,还可以考虑增加一种方法,根据具体的请求参数来控制返回类型。接口。比如我们现在定义的,所有的接口都可以可选的传递一个参数mediaType,如果值为xml,则返回xml格式的数据;如果值为json,则返回json格式的数据。SpringBootApplication公共类ApplicationimplementsWebMvcConfigurer{@OverridepublicvoidconfigureContentNegotiation(ContentNegotiationConfigurerconfigurer){configurer.favorParameter(true)//关闭accept协商方式,即不关心前端传过来的accept值//.ignoreAcceptHeader(true)//哪个放在前面,优先级更高;当上面这个accept没有被禁用时,如果请求中传递的accept不能覆盖下面两个,就会出现406错误。defaultContentType(MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML)//根据传入的参数判断返回样式mediaType.parameterName("mediaType")//在acceptHeader未禁用的情况下,如果accept的值与mediaType传入的值不一致,以mediaType传递的值为准//mediaType的值可以留空或为空,但不能为json/xml以外的值value.mediaType("json",MediaType.APPLICATION_JSON).mediaType("xml",MediaType.APPLICATION_XML);}publicstaticvoidmain(String[]args){SpringApplication.run(Application.class);}}上面的实现,多加注释,不用着急;我会一一解释。parameterName("mediaType")//当acceptHeader没有被禁用时,当accept的值与mediaType参数的值不一致时,使用med以iaType传值为准//mediaType值可以不传,也可以为空,但不能是除json/xml.mediaType("json",MediaType.APPLICATION_JSON).mediaType("xml",MediaType.APPLICATION_XML);复制代码上面三行代码主要是说现在可以根据参数的mediaType来控制返回的类型,我们新增一个接口来验证@GetMapping(path="param")publicResVoparams(@RequestParam(name="mediaType",required=false)StringmediaType){returnnewResVo<>(0,"ok",String.format("根据传参判断返回类型:%s",mediaType));}下面看传参的几种不同表现#returnjsonformatdatacurl'http://127.0.0.1:8080/param?mediaType=json'-iv#返回xml格式数据curl'http://127.0.0.1:8080/param?mediaType=xml'-iv#406错误curl'http://127.0.0.1:8080/param?mediaType=text'-iv#使用默认返回类型,json在前,所以返回json格式数据(如果把xml调到最前面,则返回xml格式数据,主要看`.defaultContentType(MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML)`)curl'http://127.0.0.1:8080/param'-iv问题:如果在请求头中传递Accept或者在接口上定义produce会怎样?指定accept时,传入的参数中指定了mediaType,以传入的参数为准,如accept:application/json,application.xml,此时mediaType=json,返回的json格式如accept:application/json,此时mediaTyep=xml,返回xml的格式如accept:text/html,此时mediaType=xml,此时返回xml的格式如accept:text/html,当此时没有传mediaType,因为无法处理text/html类型,会出现406likeaccept:application/xml,但是没有传mediaType。虽然默认优先级是json,但是返回的格式也是xml格式,这和请求头所期望的是一致的。选择mediaType设置的类型,比如produce=applicatin/json,但是mediaType=xml,这时候你会很高兴提到406。细心的朋友可能会发现,在上面的配置中,注释了一行.ignoreAcceptHeader(true)。当我们打开之后,上面提到的Accept请求头就可以随便传了,我们根本不管,当不传这个参数的时候就可以打开了。@GetMapping(path="p2",produces={"application/xml","application/json"})注意produces属性的值是有顺序的,即先定义的优先级高;当一个请求可以同时接受xml/json格式的数据时,上面的定义会保证接口当前返回的是xml格式的数据。方法2使用标准请求头accept来控制你要返回的数据类型;但是需要注意的是,使用该方法时,后台需要ContentNegotiationConfigurer.ignoreAcceptHeader(true)不能设置。实际使用这种方法时,客户需要格外注意。Acceptrequestheader中定义的MediaType顺序优于后端定义的produces顺序,所以用户需要把自己真正想要接受的数据类型放在前面,或者干脆只设置一个method。判断返回类型,常见的配置方式如configurer.favorParameter(true)//禁用accept协商方式,即不关心前端传过来的accept值//.ignoreAcceptHeader(true)//哪个放在第一位,哪个优先级高;在不禁用上面的accept的情况下,如果request中传入的accept不能覆盖下面两个,就会出现406错误。defaultContentType(MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML)//根据传入的参数判断返回样式mediaType.parameterName("mediaType")//在acceptHeader未禁用的情况下,如果accept的值与mediaType传入的值不一致,以mediaType传递的值为准。//mediaType的值可以留空或为空,但不能为json/xml以外的其他值.mediaType("json",MediaType.APPLICATION_JSON).mediaType("xml",MediaType.APPLICATION_XML);即添加这个设置后,最终的表现是:produce注意注意:当配置中忽略AcceptHeader.ignoreAcceptHeader(true)时,上面第三项无效