疯狂Spring Cloud连载(十一)——Feign的编码器与解码器


声明:本文转载自https://my.oschina.net/JavaLaw/blog/1555037,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

        本文节选自《疯狂Spring Cloud微服务架构实战》,本书将于2017年11月出版。

        Spring Cloud教学视频:https://my.oschina.net/JavaLaw/blog/1552993

本书代码共享地址:https://gitee.com/yangenxiong/SpringCloud

        本文要点

             Feign编码器与解码器

11.1 Feign的编码器与解码器

        本小节所有的案例都是单独使用Feign,Feign在Spring Cloud的使用将在后面章节讲述,请读者注意该细节。

5.2.1 编码器

        向服务发送请求的过程中,有些情况需要对请求的内容进行处理。例如服务端发布的服务接收的是JSON格式参数,而客户端使用的是对象,这种情况就可以使用编码器,将对象转换为JSON字符串。

        为服务端编写一个REST服务,处理POST请求,请见代码清单5-7。

        代码清单5-7:codes\05\5.1\rest-server\src\main\java\org\crazyit\cloud\MyController.java

	/** 	 * 参数为JSON 	 */ 	@RequestMapping(value = "/person/create", method = RequestMethod.POST,          consumes = MediaType.APPLICATION_JSON_VALUE) 	@ResponseBody 	public String createPerson(@RequestBody Person person) { 		System.out.println(person.getName() + "-" + person.getAge()); 		return "Success, Person Id: " + person.getId(); 	}

        控制器中,发布了一个“/person/create”的服务,需要传入JSON格式的请求参数。在客户端中,要调用该服务,先编写接口,再使用注解进行修饰,请见代码清单5-8。

        代码清单5-8:codes\05\5.2\feign-use\src\main\java\org\crazyit\feign\PersonClient.java

public interface PersonClient {      @RequestLine("POST /person/create")     @Headers("Content-Type: application/json")     String createPerson(Person person);      @Data     class Person {         Integer id;         String name;         Integer age;         String message;     } }

        注意在客户端的服务接口中,使用了@Headers注解,声明请求的内容类型为JSON,接下来再编写运行类,如代码清单5-9。

        代码清单5-9:codes\05\5.2\feign-use\src\main\java\org\crazyit\feign\EncoderTest.java

/**  * 运行主类  * @author 杨恩雄  *  */ public class EncoderTest {  	public static void main(String[] args) { 		// 获取服务接口 		PersonClient personClient = Feign.builder() 				.encoder(new GsonEncoder()) 				.target(PersonClient.class, "http://localhost:8080/"); 		// 创建参数的实例 		Person person = new Person(); 		person.id = 1; 		person.name = "Angus"; 		person.age = 30; 		String response = personClient.createPerson(person); 		System.out.println(response); 	} }

        运行类中,在创建服务接口实例时,使用了encoder方法来指定编码器,本案例使用了Feign提供的GsonEncoder类,该类会在发送请求过程中,将请求的对象转换为JSON字符串。Feign支持插件式的编码器,如果Feign提供的编码器无法满足要求,还可以使用自定义的编码器,这部分内容在后面章节讲述。启动服务,运行代码清单5-9,可看到服务已经调用成功,运行后输出如下:

Success, Person Id: 1

5.2.2 解码器

        编码器是对请求的内容进行处理,解码器则会对服务响应的内容进行处理,例如解析响应的JSON或者XML字符串,转换为我们所需要的对象,在代码中通过以下的代码片断设置解码器:

PersonClient personService = Feign.builder() .decoder(new GsonDecoder()) .target(PersonClient.class, "http://localhost:8080/");

        在前面章节中,我们已经使用过GsonDecoder解码器,在此不再作赘述。

5.2.3 XML的编码与解码

        除了支持JSON的处理外,Feign还为XML的处理了提供编码器与解码器,可以使用JAXBEncoder与JAXBDecoder来进行编码与解码。为服务端添加发布XML的接口,请见代码清单5-10。

        代码清单5-10:codes\05\5.1\rest-server\src\main\java\org\crazyit\cloud\MyController.java

	/** 	 * 参数与返回值均为XML 	 */ 	@RequestMapping(value = "/person/createXML", method = RequestMethod.POST,  			consumes = MediaType.APPLICATION_XML_VALUE,  			produces = MediaType.APPLICATION_XML_VALUE) 	@ResponseBody 	public String createXMLPerson(@RequestBody Person person) { 		System.out.println(person.getName() + "-" + person.getId()); 		return "<result><message>success</message></result>"; 	}

        在服务端发布的服务方法中,声明了传入的参数为XML。需要注意的是,服务端项目“rest-server”使用的是“spring-boot-starter-web”进行构建,默认情况下不支持XML接口,调用接口时会得到以下异常信息:

{"timestamp":1502705981406,"status":415,"error":"Unsupported Media Type","exception":"org.springframework.web.HttpMediaTypeNotSupportedException","message":"Content type 'application/xml;charset=UTF-8' not supported","path":"/person/createXML"}

        为服务端的pom.xml加入以下依赖即可解决该问题:

<dependency>     <groupId>com.fasterxml.jackson.jaxrs</groupId>     <artifactId>jackson-jaxrs-xml-provider</artifactId>     <version>2.9.0</version> </dependency>

        编写客户端时,先定义好服务接口以及对象,接口请见代码清单5-11。

        代码清单5-11:codes\05\5.2\feign-use\src\main\java\org\crazyit\feign\PersonClient.java

public interface PersonClient {  	@RequestLine("POST /person/createXML") 	@Headers("Content-Type: application/xml") 	Result createPersonXML(Person person);  	@Data 	@XmlRootElement 	class Person { 		@XmlElement 		Integer id; 		@XmlElement 		String name; 		@XmlElement 		Integer age; 		@XmlElement 		String message; 	}  	@Data 	@XmlRootElement 	class Result { 		@XmlElement 		String message; 	} } 

        在接口中,定义了“Content-Type”为XML,使用了JAXB的相关注解来修饰Person与Result。接下来,只需要调用createPersonXML方法即可请求服务,请见代码清单5-12。

        代码清单5-12:codes\05\5.2\feign-use\src\main\java\org\crazyit\feign\XMLTest.java

package org.crazyit.feign;  import org.crazyit.feign.PersonClient.Person; import org.crazyit.feign.PersonClient.Result;  import feign.Feign; import feign.jaxb.JAXBContextFactory; import feign.jaxb.JAXBDecoder; import feign.jaxb.JAXBEncoder;  public class XMLTest {  	public static void main(String[] args) { 		JAXBContextFactory jaxbFactory = new JAXBContextFactory.Builder().build(); 		// 获取服务接口 		PersonClient personClient = Feign.builder() 				.encoder(new JAXBEncoder(jaxbFactory)) 				.decoder(new JAXBDecoder(jaxbFactory)) 				.target(PersonClient.class, "http://localhost:8080/"); 		// 构建参数 		Person person = new Person(); 		person.id = 1; 		person.name = "Angus"; 		person.age = 30; 		// 调用接口并返回结果 		Result result = personClient.createPersonXML(person); 		System.out.println(result.message); 	} } 

        本小节的请求有一点特殊,请求服务时传入参数为XML、返回的结果也是XML,目的是为了能使编码与解码一起使用。开启服务,运行代码清单5-12,可以看到服务端与客户端的输出。

5.2.4 自定义编码器与解码器

        根据前面的两小节可知,Feign的插件式编码器与解码器,可以对请求以及结果进行处理,如果对于一些特殊的要求,可以使用自定义的编码器与解码器。实现自定义编码器,需要实现Encoder接口的encode方法,而对于解码器,则要实现Decoder接口的decode方法,例如以下的代码片断:

package org.crazyit.feign;  import java.lang.reflect.Type;  import feign.RequestTemplate; import feign.codec.EncodeException; import feign.codec.Encoder;  public class MyEncoder implements Encoder {  	public void encode(Object object, Type bodyType, RequestTemplate template) 			throws EncodeException { 		// 实现自己的Encode逻辑 	} } 

        在使用时,调用Feign的API来设置编码器或者解码器即可,实现较为简单,在此不再赘述。

本文发表于2017年10月23日 20:34
(c)注:本文转载自https://my.oschina.net/JavaLaw/blog/1555037,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2585 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1