Spring中RestTemplate的使用方法
一、REST
在互联网中,我们会通过请求url来对网络上的资源做增删改查等动作,这里的请求包含两部分:
动词,主要包括增、删、改、查;
名词,就是网络中的各种资源。
传统的非REST风格的请求方式是把动词和名词全都放在url中。
例如,对设备的操作可能是这样的:
添加设备:http://test/device/add
删除设备:http://test/device/delete
修改设备:http://test/device/modify
查找设备:http://test/device/find
这样就存在一个规范的问题,例如,添加设备这个动作的单词应该是用add还是create?http方法是用GET还是用POST?等等。
REST风格的请求方式是用http请求方法表示增删改查动作,而url中只保留名词,也就是对资源位置的描述,这样就避免了动作描述规范的问题。
还是以对设备的操作举例,REST风格的请求是这样的:
添加设备:http://test/device 请求方法是POST
删除设备:http://test/device 请求方法是DELETE
修改设备:http://test/device 请求方法是PUT
查找设备:http://test/device/:id 请求方法是GET
二、Spring中对REST请求的处理
Spring中可以使用RestTemplate来操作REST资源,主要包含以下几个方法:
getForEntity(),getForObject(),发送HTTP GET请求,getForEntity()返回的是ResponseEntity对象,里面包含响应实体对象及响应状态码,而getForObject()则直接返回响应实体对象;
postForEntity(),postForObject(),发送HTTP POST请求,postForEntity()返回的是ResponseEntity对象,里面包含响应实体对象及响应状态码,而postForObject()则直接返回响应实体对象;
put(),发送HTTP PUT请求;
delete(),发送HTTP DELETE请求;
exchange(),可以发送GET、POST、PUT和DELETE中的任意一种请求,同时还可以自定义请求头。
下面举例说明几种方法的用法:
首先创建一个实体类Device,后面的方法会用到这个实体类:
public class Device {
private String ip;
private String mac;
}
创建一个用于测试的Controller类:
@RestController
@RequestMapping(value = "/consumer")
public class ConsumerController { private RestTemplate restTemplate = new RestTemplate(); private String urlPrefix = "http://localhost:8080/test/producer"; // ...
}
1. GET请求
GET请求有两组重载方法:
1.1 getForEntity()
这个方法有多个重载方法:
方法一:
getForEntity(String url, Class<T> responseType, Object... uriVariables)
其中,url就是请求的url,responseType是返回的实体类类型,uriVariables是uri或请求参数。
代码示例如下:
@RequestMapping(value = "/get1")
public String testGetForEntity1() {
String url = urlPrefix + "/get";
ResponseEntity<Device> response = restTemplate.getForEntity(url, Device.class);
System.out.println("Device: " + response.getBody() + ", code: " + response.getStatusCodeValue());
return response.getBody().toString();
}
返回的response中既包含返回的实体对象(通过response.getBody()获取),又包含返回状态码(通过response.getStatusCodeValue()获取)。
这里的url中没有任何参数,所以uriVariables为空。如果url中需要传一些参数,可以通过以下方式传递:
@RequestMapping(value = "/get2")
public String testGetForEntity3() {
String url = urlPrefix + "/get?protocol={protocol}&operator={operator}";
ResponseEntity<Device> response = restTemplate.getForEntity(url, Device.class, "NBIot", "ChinaMobile");
System.out.println("Device: " + response.getBody() + ", code: " + response.getStatusCodeValue());
return response.getBody().toString();
}
这里传了两个参数protocol和operator。
方法二:
getForEntity(String url, Class<T> responseType, Map<String,?> uriVariables)
这种方法是将uriVariables用Map方式传入,如果参数比较多的话,这种方式方便方法之间的参数传递。
代码示例如下:
@RequestMapping(value = "/get3")
public String testGetForEntity2() {
Map<String, String> classifyMap = new HashMap<>();
classifyMap.put("protocol", "NBIot");
classifyMap.put("operator", "ChinaMobile");
String url = urlPrefix + "/get?protocol={protocol}&operator={operator}";
ResponseEntity<Device> response = restTemplate.getForEntity(url, Device.class, classifyMap);
System.out.println("Device: " + response.getBody() + ", code: " + response.getStatusCodeValue());
return response.getBody().toString();
}
方法三:
getForEntity(URI url, Class<T> responseType)
这种方法是把String类型的url替换成java.net.URI类型的url。
1.2 getForObject()
这个方法和getForEntity()的3个重载方法请求参数是完全一样的,不同的是getForObject()直接返回的是实体对象,而没有返回状态码。如果不关注状态码,只关注返回内容,可以使用这个方法。
方法一:
getForObject(String url, Class<T> responseType, Object... uriVariables)
代码示例如下:
不包含请求参数的方法:
@RequestMapping(value = "/get4")
public String testGetForObject1() {
String url = urlPrefix + "/get";
Device device = restTemplate.getForObject(url, Device.class);
System.out.println("Device: " + device);
return device.toString();
}
包含请求参数的方法:
@RequestMapping(value = "/get5")
public String testGetForObject2() {
String url = urlPrefix + "/get?protocol={protocol}&operator={operator}";
Device device = restTemplate.getForObject(url, Device.class, "NBIot", "ChinaMobile");
System.out.println("Device: " + device);
return device.toString();
}
方法二:
getForObject(String url, Class<T> responseType, Map<String,?> uriVariables)
代码示例如下:
@RequestMapping(value = "/get6")
public String testGetForObject3() {
Map<String, String> classifyMap = new HashMap<>();
classifyMap.put("protocol", "NBIot");
classifyMap.put("operator", "ChinaMobile");
String url = urlPrefix + "/get?protocol={protocol}&operator={operator}";
Device device = restTemplate.getForObject(url, Device.class, classifyMap);
System.out.println("Device: " + device);
return device.toString();
}
方法三:
getForObject(URI url, Class<T> responseType)
2. POST请求
POST请求有两组重载方法:
postForEntity()
这个方法也有多个重载方法,和getForEntity()方法的传入参数非常类似,只是多了一个request参数,这个参数就是POST请求body体重的参数。
方法一:
postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
代码示例如下:
@RequestMapping(value = "/post1")
public String testPostForEntity1() {
Device device = Device.builder().ip("1.2.3.4").mac("FF:FF:FF:FF:FF:FF").build();
String url = urlPrefix + "/post";
ResponseEntity<Device> response = restTemplate.postForEntity(url, device, Device.class);
System.out.println("Device: " + response.getBody() + ", code: " + response.getStatusCodeValue());
return response.getBody().toString();
}
请求url中也可以包含参数,代码示例如下:
@RequestMapping(value = "/post2")
public String testPostForEntity2() {
Device device = Device.builder().ip("1.2.3.4").mac("FF:FF:FF:FF:FF:FF").build();
Map<String, String> classifyMap = new HashMap<>();
classifyMap.put("protocol", "NBIot");
classifyMap.put("operator", "ChinaMobile");
String url = urlPrefix + "/post?protocol={protocol}&operator={operator}";
ResponseEntity<Device> response = restTemplate.postForEntity(url, device, Device.class, classifyMap);
System.out.println("Device: " + response.getBody() + ", code: " + response.getStatusCodeValue());
return response.getBody().toString();
}
方法二:
postForEntity(String url, Object request, Class<T> responseType, Map<String,?> uriVariables)
代码示例如下:
@RequestMapping(value = "/post3")
public String testPostForEntity3() {
Device device = Device.builder().ip("1.2.3.4").mac("FF:FF:FF:FF:FF:FF").build();
String url = urlPrefix + "/post?protocol={protocol}&operator={operator}";
ResponseEntity<Device> response = restTemplate.postForEntity(url, device, Device.class, "NBIot", "ChinaMobile");
System.out.println("Device: " + response.getBody() + ", code: " + response.getStatusCodeValue());
return response.getBody().toString();
}
方法三:
postForEntity(URI url, Object request, Class<T> responseType)
postForObject()
和前面的GET方法类似,这个方法也是只返回请求对象,不返回请求状态码。
方法一:
postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
不带请求参数的代码示例:
@RequestMapping(value = "/post4")
public String testForObject1() {
Device device = Device.builder().ip("1.2.3.4").mac("FF:FF:FF:FF:FF:FF").build();
String url = urlPrefix + "/post";
Device responseDevice = restTemplate.postForObject(url, device, Device.class);
System.out.println("Device: " + responseDevice);
return responseDevice.toString();
}
带请求参数的代码示例:
@RequestMapping(value = "/post5")
public String testForObject2() {
Device device = Device.builder().ip("1.2.3.4").mac("FF:FF:FF:FF:FF:FF").build();
Map<String, String> classifyMap = new HashMap<>();
classifyMap.put("protocol", "NBIot");
classifyMap.put("operator", "ChinaMobile");
String url = urlPrefix + "/post?protocol={protocol}&operator={operator}";
Device responseDevice = restTemplate.postForObject(url, device, Device.class, classifyMap);
System.out.println("Device: " + responseDevice);
return responseDevice.toString();
}
方法二:
postForObject(String url, Object request, Class<T> responseType, Map<String,?> uriVariables)
代码示例如下:
@RequestMapping(value = "/post6")
public String testForObject3() {
Device device = Device.builder().ip("1.2.3.4").mac("FF:FF:FF:FF:FF:FF").build();
String url = urlPrefix + "/post?protocol={protocol}&operator={operator}";
Device responseDevice = restTemplate.postForObject(url, device, Device.class, "NBIot", "ChinaMobile");
System.out.println("Device: " + responseDevice);
return responseDevice.toString();
}
方法三:
postForObject(URI url, Object request, Class<T> responseType)
3. PUT请求
POST请求用来创建资源,有时候在创建资源的时候会返回已创建的资源的相关信息,比如资源的ID等。
GET请求是用来查询资源的,所以一定会返回资源信息。
而PUT请求用来修改资源,通常我们只关注修改成功与否,不需要返回相关的资源信息。因此PUT的方法没有区分xxxForEntity()和xxxForObject()方法,它只有一种方法:
put()
它有三种重载方法,返回类型都是void。
方法一:
put(String url, Object request, Object... uriVariables)
和POST的使用方法完全一样,只是不需要关注返回结果。
不带请求参数的代码示例如下:
@RequestMapping(value = "/put1")
public void testPut1() {
Device device = Device.builder().ip("1.2.3.4").mac("FF:FF:FF:FF:FF:FF").build();
String url = urlPrefix + "/put";
restTemplate.put(url, device);
}
带请求参数的代码示例如下:
@RequestMapping(value = "/put2")
public void testPut2() {
Device device = Device.builder().ip("1.2.3.4").mac("FF:FF:FF:FF:FF:FF").build();
String url = urlPrefix + "/put?protocol={protocol}&operator={operator}";
restTemplate.put(url, device, "NBIot", "ChinaMobile");
}
方法二:
put(String url, Object request, Map<String,?> uriVariables)
代码示例如下:
@RequestMapping(value = "/put3")
public void testPut3() {
Map<String, String> classifyMap = new HashMap<>();
classifyMap.put("protocol", "NBIot");
classifyMap.put("operator", "ChinaMobile");
Device device = Device.builder().ip("1.2.3.4").mac("FF:FF:FF:FF:FF:FF").build();
String url = urlPrefix + "/put?protocol={protocol}&operator={operator}";
restTemplate.put(url, device, classifyMap);
}
方法三:
put(URI url, Object request)
4. DELETE请求
DELETE请求更简单,既没有请求body体,也没有返回对象,它也只有一种方法:
delete()
和其它方法一样,也有三种重载方法:
方法一:
delete(String url, Object... uriVariables)
代码示例如下:
@RequestMapping(value = "/delete1")
public void testDelete1() {
String url = urlPrefix + "/delete";
restTemplate.delete(url);
} @RequestMapping(value = "/delete2")
public void testDelete2() {
String url = urlPrefix + "/delete?protocol={protocol}&operator={operator}";
restTemplate.delete(url, "NBIot", "ChinaMobile");
}
方法二:
delete(String url, Map<java.lang.String,?> uriVariables)
代码示例如下:
@RequestMapping(value = "/delete3")
public void testDelete3() {
Map<String, String> classifyMap = new HashMap<>();
classifyMap.put("protocol", "NBIot");
classifyMap.put("operator", "ChinaMobile");
String url = urlPrefix + "/delete?protocol={protocol}&operator={operator}";
restTemplate.delete(url, classifyMap);
}
方法三:
delete(URI url)
5. 通用请求接口
RestTemplate还有一个更强大,而且更通用的接口exchange(),它同时支持GET、POST、PUT、DELETE方法,并且还可以添加请求参数头。
方法一:
exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Map<String,?> uriVariables)
exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables)
exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType)
这个方法比前面讲过的专用接口多了两个参数,其中:
method表示HTTP请求方法,也就是GET、POST等;
requestEntity封装了请求消息对象,POST和PUT会用到,同时requestEntity中还可以添加请求头参数。
GET请求代码示例:
@RequestMapping(value = "/exchange1")
public String testExchangeForGet1() throws URISyntaxException {
String url = urlPrefix + "/get?protocol={protocol}&operator={operator}";
ResponseEntity<Device> response = restTemplate.exchange(url, HttpMethod.GET, null, Device.class, "NBIot", "ChinaMobile");
System.out.println("Device: " + response.getBody() + ", code: " + response.getStatusCodeValue());
return response.getBody().toString();
}
GET请求不需要请求消息,因此requestEntity为null。
POST请求代码示例:
@RequestMapping(value = "/exchange2")
public String testExchangeForPost1() throws URISyntaxException {
String url = urlPrefix + "/post";
Device device = Device.builder().ip("1.2.3.4").mac("FF:FF:FF:FF:FF:FF").build();
HttpEntity<Device> requestEntity = new HttpEntity<Device>(device, null);
ResponseEntity<Device> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, Device.class);
System.out.println("Device: " + response.getBody() + ", code: " + response.getStatusCodeValue());
return response.getBody().toString();
}
这里用Device构造了一个requestEntity对象。
PUT请求代码示例:
@RequestMapping(value = "/exchange3")
public void testExchangeForPut() throws URISyntaxException {
String url = urlPrefix + "/put";
Device device = Device.builder().ip("1.2.3.4").mac("FF:FF:FF:FF:FF:FF").build();
HttpEntity<Device> requestEntity = new HttpEntity<Device>(device, null);
ResponseEntity<Device> response = restTemplate.exchange(url, HttpMethod.PUT, requestEntity, Device.class);
System.out.println("code: " + response.getStatusCodeValue());
}
DELETE请求代码示例:
@RequestMapping(value = "/exchange4")
public void testExchangeForDelete() throws URISyntaxException {
String url = urlPrefix + "/delete";
ResponseEntity<Device> response = restTemplate.exchange(url, HttpMethod.DELETE, null, Device.class);
System.out.println("code: " + response.getStatusCodeValue());
}
方法二:
url和method都可以封装到requestEntity中,这样的话方法签名看上去就更简洁了:
exchange(RequestEntity<?> requestEntity, Class<T> responseType)
exchange(RequestEntity<?> requestEntity, ParameterizedTypeReference<T> responseType)
GET请求代码示例:
@RequestMapping(value = "/exchange5")
public String testExchangeForGet2() throws URISyntaxException {
String url = urlPrefix + "/get";
RequestEntity<Device> requestEntity = new RequestEntity<Device>(HttpMethod.GET, new URI(url));
ResponseEntity<Device> response = restTemplate.exchange(requestEntity, Device.class);
System.out.println("Device: " + response.getBody() + ", code: " + response.getStatusCodeValue());
return response.getBody().toString();
}
POST请求代码示例:
@RequestMapping(value = "/exchange6")
public String testExchangeForPost2() throws URISyntaxException {
String url = urlPrefix + "/post";
Device device = Device.builder().ip("1.2.3.4").mac("FF:FF:FF:FF:FF:FF").build();
RequestEntity<Device> requestEntity = new RequestEntity<Device>(device, HttpMethod.POST, new URI(url));
ResponseEntity<Device> response = restTemplate.exchange(requestEntity, Device.class);
System.out.println("Device: " + response.getBody() + ", code: " + response.getStatusCodeValue());
return response.getBody().toString();
}
有时候,我们不仅仅返回一个对象,而是返回一个容器类,比如List。
如果我们使用之前的方法,代码可能是这样的:
@RequestMapping(value = "/exchange7")
public List testExchangeForNoType() throws URISyntaxException {
String url = urlPrefix + "/getall";
ResponseEntity<List> response = restTemplate.exchange(url, HttpMethod.GET, null, List.class);
List deviceList = response.getBody();
System.out.println("Device: " + deviceList + ", code: " + response.getStatusCodeValue());
return response.getBody();
}
如果我们跟踪代码就会发现,response.getBody()方法返回的不是我们所期望的List<Device>,而是一个List<<LinkedHashMap<K,V>>。因为exchange不知道List中具体是什么类型的对象。
这时我们可以使用下面这几个支持泛型的方法:
exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType, Map<String,?> uriVariables)
exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType, Object... uriVariables)
exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType)
代码示例如下:
@RequestMapping(value = "/exchange8")
public List<Device> testExchangeForParameterizedTypeReference() throws URISyntaxException {
String url = urlPrefix + "/getall";
ParameterizedTypeReference<List<Device>> parameterizedTypeReference = new ParameterizedTypeReference<List<Device>>(){};
ResponseEntity<List<Device>> response = restTemplate.exchange(url, HttpMethod.GET, null, parameterizedTypeReference);
List<Device> deviceList = response.getBody();
System.out.println("Device: " + deviceList + ", code: " + response.getStatusCodeValue());
return response.getBody();
}
如果跟踪代码会发现,response.getBody()这时候已经返回的是一个List<Device>类型的列表。
6. 添加头参数
有时候需要在请求中添加一些头参数,比如指定字符编码、指定cookie信息等,这时候可以把头参数塞到requestEntity对象中。
代码示例如下:
@RequestMapping(value = "/exchange10")
public Device testForHeader() throws URISyntaxException {
String url = urlPrefix + "/post";
Device device = Device.builder().ip("1.2.3.4").mac("FF:FF:FF:FF:FF:FF").build();
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.add("Content-Type", "application/json;charset=UTF-8");
RequestEntity<Device> requestEntity = new RequestEntity<Device>(device, requestHeaders, HttpMethod.POST, new URI(url)); ResponseEntity<Device> response = restTemplate.exchange(requestEntity, Device.class);
System.out.println("Device: " + response.getBody() + ", code: " + response.getStatusCodeValue());
return response.getBody();
}
7. 处理返回错误
有时候HTTP请求并不能正常返回,这时候我们需要对异常返回做相应的处理。
虽然RestTemplate在返回的ResponseEntity中会包含错误码,但是在发送请求遇到错误的时候并不会把错误码和错误信息直接放在这个ResponseEntity中,而是会直接抛出异常,我们需要对异常进行处理。
错误返回可以分为以下几类:
HttpClientErrorException:4xx错误,属于客户端错误,比如错误的请求,鉴权失败等;
HttpServerErrorException:5xx错误,属于服务端错误,比如服务端暂时不可用,服务端内部错误等;
UnknownHttpStatusCodeException:未知错误码错误,这种可能属于协议错误,返回的HTTP消息的没有错误码或者是错误码不在HTTP协议定义的范围内。
代码示例如下:
@RequestMapping(value = "/exchange11")
public Device testForResponse() throws URISyntaxException {
String url = urlPrefix + "/get?protocol={protocol}&operator={operator}";
RequestEntity<Device> requestEntity = new RequestEntity<Device>(HttpMethod.GET, new URI(url));
try {
ResponseEntity<Device> response = restTemplate.exchange(requestEntity, Device.class);
System.out.println("Device: " + response.getBody() + ", code: " + response.getStatusCodeValue());
return response.getBody();
} catch(HttpClientErrorException ce) {
// 处理4xx错误
} catch(HttpServerErrorException se) {
// 处理5xx错误
} catch(UnknownHttpStatusCodeException ue) {
// 处理未知错误
}
return null;
}
Spring中RestTemplate的使用方法的更多相关文章
- Spring中RestTemplate进行Http调用
Spring中的RestTemplate类源自spring-web,http调用中设置超时时间.设置连接池管理等非常重要,保证了系统的可用性,避免了长时间连接不上或者等待数据返回,拖垮系统. 现贴出工 ...
- 面试官:spring中定义bean的方法有哪些?我一口气说出了12种,把面试官整懵了。
前言 在庞大的java体系中,spring有着举足轻重的地位,它给每位开发者带来了极大的便利和惊喜.我们都知道spring是创建和管理bean的工厂,它提供了多种定义bean的方式,能够满足我们日常工 ...
- 【Spring Framework】12种spring中定义bean的方法
前言 在庞大的java体系中,spring有着举足轻重的地位,它给每位开发者带来了极大的便利和惊喜.我们都知道spring是创建和管理bean的工厂,它提供了多种定义bean的方式,能够满足我们日常工 ...
- Spring中@Async注解实现“方法”的异步调用
原文:http://www.cnblogs.com/zhengbin/p/6104502.html 简单介绍: Spring为任务调度与异步方法执行提供了注解支持.通过在方法上设置@Async注解,可 ...
- SSM-Spring-12:Spring中NameMatchMethodPointcutAdvisor名称匹配方法切入点顾问
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- advice 是通知advisor 是顾问 顾问(Advisor) 通知Advice是Spring提供的一种切 ...
- spring中的多线程aop方法拦截
日常开发中,常用spring的aop机制来拦截方法,记点日志.执行结果.方法执行时间啥的,很是方便,比如下面这样:(以spring-boot项目为例) 一.先定义一个Aspect import org ...
- spring中得到servletContext对象方法
1.spring得到servletContext,这个和session没有什么关系,上下文可以说是一个session容器,一个上下文可以有多个会话session 在web.xml中有以下配置后.加入s ...
- spring 中StoredProcedure的使用方法
StoredProcedure是一个抽象类,必须写一个子类来继承它,这个类是用来简化JDBCTemplate运行存储过程操作的. 首先我们写一个实现类: package com.huaye.frame ...
- Spring中使用Ehcache的方法和注意事项
如何调用方法数据增加缓存 @Cacheable(value="MY_CACHE", key="'cache_business_' + #business_id" ...
随机推荐
- bzoj 3232: 圈地游戏【分数规划+最小割】
数组开小导致TTTTTLE-- 是分数规划,设sm为所有格子价值和,二分出mid之后,用最小割来判断,也就是判断sm-dinic()>=0 这个最小割比较像最大权闭合子图,建图是s像所有点连流量 ...
- LuoguP2700逐个击破【并查集/生成树/正难则反】By cellur925
题目传送门 题目大意:给你一棵树,求把其中k个点相互隔离(不连通)所需要的边权代价. 这题我开始是想要求出把k个点联通的最小代价的,但后来发现还是实现起来比较困难,题解里貌似也没有这种做法,于是就鸽了 ...
- tomcat复习
javaEE 服务器: java企业版服务器:是一个标准 BS/CS: 1> CS: client/Server 优点:易操作性比较高 缺点:客户端需要升级维护. 2> BS: Brows ...
- Hash环/一致性Hash原理
当前,Memcached.Redis这类分布式kv缓存已经非常普遍.从本篇开始,本系列将分析分布式缓存相关的原理.使用策略和最佳实践. 我们知道Memcached的分布式其实是一种“伪分布式”,也就是 ...
- MySQLDump在使用之前一定要想到的事情 [转载]
转载于:http://blog.itpub.net/29254281/viewspace-1392757/ MySQLDump经常用于迁移数据和备份. 下面创建实验数据,两个数据库和若干表create ...
- mysql 三大范式【转载】
第一范式(1NF,normal format):字段不能再分. 这是字段的原子性.例如:字段“学期时间”:2014-9-1,2015-1-15. 这个字段“学期时间”可以再分为“学期开始时间”,201 ...
- HtmlUnit爬取Ajax动态生成的页面内容
HtmlUnit说白了就是一个浏览器,这个浏览器是用Java写的无界面的浏览器,正因为其没有界面,因此执行的速度还是可以滴. HtmlUnit提供了一系列的API,这些API可以干的功能比较多,如表单 ...
- C#中this指针的用法示例
这篇文章主要介绍了C#中this指针的用法,对初学者而言是非常重要的概念,必须加以熟练掌握,需要的朋友可以参考下. 本文实例展示了C#中this指针的用法,对于初学者进一步牢固掌握C#有很大帮助,具体 ...
- 关于重置功能(type="reset")的相关问题
当一个按钮具有 type="reset";的按钮是具有重置表单标签的功能的,但是当具有type="hidden"; 属性的标签的值就不会被重置,这点要留意.可以 ...
- pre-network android 网络优化预加载框架
网络优化是所有app开发中非常重要的一部分,如果将网络请求前置就是在点击跳转activity之前开始网络加载那么速度将会有质的提升.也就是网络预先加载框框架. 网络预加载框架,监听式网络前置加载框架- ...