【第七章】 springboot + retrofit
retrofit:一套RESTful架构的Android(Java)客户端实现。
好处:
- 基于注解
- 提供JSON to POJO,POJO to JSON,网络请求(POST,GET,PUT,DELETE等)封装
- 可以看做是对HttpClient的再次封装
1、为了做测试,建立了一个新的springboot项目"myboot2",项目结构如下:
1.1、pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.xxx</groupId> <artifactId>myboot2</artifactId> <version>1.0-SNAPSHOT</version> <properties> <java.version>1.8</java.version><!-- 官方推荐 --> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.2.5.RELEASE</version> </parent> <!-- 引入实际依赖 --> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 使用swagger --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.2.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
1.2、Application.java
package com.xxx.secondboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer; import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; import springfox.documentation.swagger2.annotations.EnableSwagger2; @SpringBootApplication @EnableSwagger2 public class Application implements EmbeddedServletContainerCustomizer{ public static void main(String[] args) { SpringApplication.run(Application.class, args); } /** * EmbeddedServletContainerCustomizer接口的未实现方法 * 指定容器的启动端口,之后再浏览器输入localhost:8081/swagger-ui.html即可 */ public void customize(ConfigurableEmbeddedServletContainer container) { container.setPort(8081); } }
说明:
- 实现了EmbeddedServletContainerCustomizer接口,并实现了其方法customize(ConfigurableEmbeddedServletContainer container),指定了该服务的启动端口是8081,这样在服务myboot(启动端口:8080)启动时,就不会存在端口冲突问题了.
1.3、Hotel.java
package com.xxx.secondboot.domain; public class Hotel { private int id; private String hotelname; public Hotel() { } public Hotel(int id, String hotelname) { this.id = id; this.hotelname = hotelname; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getHotelname() { return hotelname; } public void setHotelname(String hotelname) { this.hotelname = hotelname; } }
1.4、HotelController.java
package com.xxx.secondboot.web; import java.util.ArrayList; import java.util.List; import org.springframework.web.bind.annotation.RequestBody; 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; import com.xxx.secondboot.domain.Hotel; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @RestController @RequestMapping("/hotel") @Api("HotelController相关api") public class HotelController { @ApiOperation("获取酒店Hotel信息:getHotelWithQueryParameter") @RequestMapping(value="/getHotelWithQueryParameter",method=RequestMethod.GET) public Hotel getHotelWithQueryParameter(@RequestParam("hotelname") String hotelname) { if(hotelname.equals("nana")){ return new Hotel(777, "假日酒店"); } return new Hotel(1314, "玫瑰酒店"); } @ApiOperation("获取酒店Hotel信息:getHotelList") @RequestMapping(value="/getHotelList",method=RequestMethod.POST) public List<Hotel> getHotelList() { List<Hotel> hotelList = new ArrayList<>(); hotelList.add(new Hotel(1314, "玫瑰酒店")); hotelList.add(new Hotel(2046, "2046酒店")); return hotelList; } @ApiOperation("获取酒店Hotel信息:getHotelListWithBody") @RequestMapping(value="/getHotelListWithBody",method=RequestMethod.POST) public List<Hotel> getHotelListWithBody(@RequestBody Hotel hotel) { List<Hotel> hotelList = new ArrayList<>(); if(hotel.getHotelname().equals("武林酒店")){ hotelList.add(new Hotel(13141, "玫瑰酒店1")); hotelList.add(new Hotel(20461, "2046酒店1")); return hotelList; } hotelList.add(new Hotel(1314, "玫瑰酒店")); hotelList.add(new Hotel(2046, "2046酒店")); return hotelList; } }
说明:该类提供了三个方法,也是将来myboot服务远程调用的三个方法。
2、myboot项目基于上一节的结构继续编写
2.1、pom.xml
<!-- retrofit --> 2 <dependency> 3 <groupId>com.squareup.retrofit</groupId> 4 <artifactId>retrofit</artifactId> 5 <version>1.9.0</version> 6 </dependency>
说明:引入retrofit1.9.0依赖,与2.0的差别很大。
2.2、RestAdapterConfig.java
package com.xxx.firstboot.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import retrofit.RestAdapter; @Configuration public class RestAdapterConfig { /** * 获取RestAdapter单例Bean * @return */ @Bean public RestAdapter getRestAdapter(){ /** * setEndpoint("http://localhost:8081"):指定基本的URL, * API接口中的URL是相对于该URL的路径的, * 不能少了协议名,例如写成:localhost:8081就不行 */ RestAdapter adapter = new RestAdapter.Builder() .setEndpoint("http://localhost:8081") .build(); return adapter; } }
说明:
- 使用 @Configuration+@Bean 构建RestAdapter单例。
- 在构建的过程中,一定要有setEndpoint("http://localhost:8081")方法,该方法指定了基本的URL(即:指定协议+IP+port)
2.3、HotelAPI.java
package com.xxx.firstboot.retrofit.api; import java.util.List; import com.xxx.firstboot.domain.Hotel; import retrofit.http.Body; import retrofit.http.GET; import retrofit.http.POST; import retrofit.http.Query; public interface HotelAPI { /** * GET请求带查询参数 */ @GET("/hotel/getHotelWithQueryParameter") public Hotel getHotelWithQueryParameter(@Query("hotelname") String hotelname); /** * POST请求 */ @POST("/hotel/getHotelList") public List<Hotel> getHotelList(); /** * POST请求,带参数JavaBean */ @POST("/hotel/getHotelListWithBody") public List<Hotel> getHotelListWithBody(@Body Hotel hotel); }
说明:
- 该接口指定了调用远程服务的方法的基本路径与参数以及返回值等
- 路径都是相对路径,相对于setEndpoint("http://localhost:8081")指定的路径
- 方式有@GET/@POST/@PUT/@DELETE等
- 传递参数在get方式中可以直接将参数连到URL上去
- 传递参数使用@Query(服务被调用方使用@RequestParam接收),路径中的传递参数使用@Path(Restful风格),还可以直接传递一个对象@Body(服务被调用方使用@RequestBody接收),参数在请求头中@Header(服务被调用方使用@RequestHeader接收)
- 依旧要建一个Hotel类,最好与myboot2中的相同,不同也没关系
2.4、HotelAPIConfig.java
package com.xxx.firstboot.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.xxx.firstboot.retrofit.api.HotelAPI; import retrofit.RestAdapter; @Configuration public class HotelAPIConfig { @Autowired private RestAdapter adapter; @Bean public HotelAPI getHotelAPI(){ return adapter.create(HotelAPI.class); } }
说明:
- 使用 @Configuration+@Bean 构建HotelAPI单例。
- HotelAPI接口实例是由RestAdapter来构建的,所以需要注入了RestAdapter
经过以上步骤后,之后就可以直接在其他类中注入HotelAPI实例来像普通的bean进行操作了。
2.5、UserService.java
@Autowired private HotelAPI hotelApi; public Hotel getHotelFromMyboot2WithQueryParameter(String hotelname){ return hotelApi.getHotelWithQueryParameter(hotelname); } public List<Hotel> getHotelFromMyboot2List(){ return hotelApi.getHotelList();//测试post请求 } public List<Hotel> getHotelFromMyboot2ListWithBody(Hotel hotel){ return hotelApi.getHotelListWithBody(hotel);//测试post请求 }
说明:
- service中注入了HotelAPI实例,使用该实例调用接口方法
- 其实,retrofit的接口的注入和使用与mybatis的注解方式的mapper接口的使用相似
2.6、UserController.java
@Autowired private UserService userService; @ApiOperation("获取酒店信息,测试GETWithQueryParameter") @RequestMapping(value="/getHotelWithQueryParameter",method=RequestMethod.GET) public Hotel getHotel(@RequestParam("hotelname") String hotelname) { return userService.getHotelFromMyboot2WithQueryParameter(hotelname); } @ApiOperation("获取酒店信息,测试POST") @RequestMapping(value="/getHotelList",method=RequestMethod.GET) public List<Hotel> getHotelList() { return userService.getHotelFromMyboot2List(); } @ApiOperation("获取酒店信息,测试POST") @RequestMapping(value="/getHotelListWithBody",method=RequestMethod.GET) public List<Hotel> getHotelListWithBody() { return userService.getHotelFromMyboot2ListWithBody(new Hotel(888, "武林酒店")); }
测试:
首先,启动服务myboot2,浏览器输入"localhost:8081/swagger-ui.html"可以查看服务是否启动成功。
其次,启动服务myboot,浏览器输入"localhost:8080/swagger-ui.html",再进行相应接口的测试即可。
参考自:
http://www.tuicool.com/articles/26jUZjv
【第七章】 springboot + retrofit的更多相关文章
- 第七章 springboot + retrofit(转载)
本篇博客转发自:http://www.cnblogs.com/java-zhao/p/5350861.html retrofit:一套RESTful架构的Android(Java)客户端实现. 好处: ...
- 第七章 springboot + retrofit
retrofit:一套RESTful架构的Android(Java)客户端实现. 好处: 基于注解 提供JSON to POJO,POJO to JSON,网络请求(POST,GET,PUT,DELE ...
- 第十六章 springboot + OKhttp + String.format
模拟浏览器向服务器发送请求四种方式: jdk原生的Http包下的一些类 httpclient(比较原始,不怎么用了):第一章 HttpClient的使用 Okhttp(好用,推荐) retrofit( ...
- 精通Web Analytics 2.0 (9) 第七章:失败更快:爆发测试与实验的能量
精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第七章:失败更快:爆发测试与实验的能量 欢迎来到实验和测试这个棒极了的世界! 如果Web拥有一个超越所有其他渠道的巨大优势,它就 ...
- 《Entity Framework 6 Recipes》中文翻译系列 (38) ------ 第七章 使用对象服务之动态创建连接字符串和从数据库读取模型
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第七章 使用对象服务 本章篇幅适中,对真实应用中的常见问题提供了切实可行的解决方案. ...
- 《Entity Framework 6 Recipes》中文翻译系列 (41) ------ 第七章 使用对象服务之标识关系中使用依赖实体与异步查询保存
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 7-7 标识关系中使用依赖实体 问题 你想在标识关系中插入,更新和删除一个依赖实体 ...
- Java语言程序设计(基础篇) 第七章 一维数组
第七章 一维数组 7.2 数组的基础知识 1.一旦数组被创建,它的大小是固定的.使用一个数组引用变量,通过下标来访问数组中的元素. 2.数组是用来存储数据的集合,但是,通常我们会发现把数组看作一个存储 ...
- objective-c第七章课后练习2
题:改变第七章例子中print方法,增加bool参数,判断如果是YES则对分数进行约简 @interface Fraction : NSObject { //int num,den; } @prope ...
- 读《编写可维护的JavaScript》第七章总结
第七章 事件处理 7.1 典型用法 作者首先给了个我们一个处理事件的方法.看起来也没啥俩样,不过后来给出的优化方法很值得学习: // 不好的写法 function handleClick(even ...
- 第七章 LED将为我们闪烁:控制发光二极管
第七章 LED将为我们闪烁:控制发光二极管 本章我们将会看到一个完整的linux驱动程序,通过linux驱动程序控制LED的四个小灯,通俗的说就是通过向linux驱动程序来控制LED小灯的开关.用到 ...
随机推荐
- sass不识别中文字符的问题
进入Koala安装目录,例如:C:\Program Files (x86)\Koala\rubygems\gems\sass-3.4.9\lib\sass 或者 C:\Ruby\lib\ruby\ge ...
- 代码实现SQL SERVER TCP/IP协议配置
代码实现SQL SERVER TCP/IP协议配置 SET NOCOUNT ON ) ,) ,) SET @Root = 'HKEY_LOCAL_MACHINE' SET @Path = 'Softw ...
- dedecms获取当前文章所在栏目URL
我们知道dedecms有一个面包屑导航的调用函数,{dede:field name='position'/},这个样式是固定的,有时要个性化一些的话需要修改很多地方,那么织梦cms有没其他方法获取当前 ...
- 005-四种常见的 POST 提交数据方式
1.http请求方法 HTTP Method RFC Request Has Body Response Has Body Safe Idempotent Cacheable GET RFC 7231 ...
- edgeR使用学习【转载】
转自:http://yangl.net/2016/09/27/edger_usage/ 1.Quick start 2. 利用edgeR分析RNA-seq鉴别差异表达基因: #加载软件包 librar ...
- col-md-1
.col-md-12 { width: 100%; } .col-md-11 { width: 91.66666666666666%; } .col-md-10 { widt ...
- 使用免费的Let's Encrypt通配符证书 升级我们的网站
Let's Encrypt通配符证书的官方启用日期:2018年3月13日 也就是说,2018年3月13日之后,我们就可以使用Let's Encrypt通配符证书了,当然是免费的. Let's Encr ...
- data.frame和matrix的一些操作
编写脚本的时候经常会涉及到对data.frame或matrix类型数据的操作,比如取指定列.取指定行.排除指定列或行.根据条件取满足条件的列或行等.在R中,这些操作都是可以通过简单的一条语句就能够实现 ...
- opencv之颜色过滤只留下图片中的红色区域
如图,这次需要在图片中找到卷尺的红色刻度,所以需要对图像做过滤,只留下红色部分. 一开始的想法是分别找到RGB值,然后找到红色区域的部分保留就可以了,不过好像很难确定红色区域的RGB取值范围,所以要把 ...
- 浅谈Android View滑动冲突
引言 上一篇文章我们从源码的角度介绍了View事件分发机制,这一篇文章我们就通过介绍滑动冲突的规则和一个实例来更加深入的学习View的事件分发机制. 1.外部滑动方向和内部滑动方向不一致 考虑这样一种 ...