使用HttpURLConnection发起HTTP请求
2019-11-04 本文已影响0人
SevenLin1993
技术公众号:Java In Mind(Java_In_Mind),欢迎关注!
HttpURLConnection介绍
支持 HTTP 特定功能的 URLConnection。有关详细信息,请参阅 the spec 。
每个 HttpURLConnection 实例都可用于生成单个请求,但是其他实例可以透明地共享连接到 HTTP 服务器的基础网络。请求后在 HttpURLConnection 的 InputStream 或 OutputStream 上调用 close() 方法可以释放与此实例关联的网络资源,但对共享的持久连接没有任何影响。如果在调用 disconnect() 时持久连接空闲,则可能关闭基础套接字。
简单来说,HttpURLConnection就是Java提供的发起HTTP请求的基础类库,提供了HTTP请求的基本能力,不过封装比较少,使用时都要自己设置,也需要自己处理请求流和响应流,虽然实际使用比较少,但也可以作为学习研究研究,下面来简单使用一下:
模拟服务
@RestController
@RequestMapping("/demo")
@SpringBootApplication
@Slf4j
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
private List<Foo> foos = new CopyOnWriteArrayList<>();
@GetMapping("/list")
public ResponseEntity list(@RequestParam(value = "name") String name) {
log.info("accept a list request...");
return ResponseEntity.ok(foos.stream().filter(i -> i.getName().equals(name)).collect(Collectors.toList()));
}
@PostMapping
public ResponseEntity create(@RequestBody Foo foo) {
log.info("accept create request,foo:{}", foo);
foos.add(foo);
return ResponseEntity.ok(foo);
}
@GetMapping("/error")
public ResponseEntity error() {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("error");
}
@GetMapping("/redirect")
public ResponseEntity redirect() {
return ResponseEntity.status(HttpStatus.FOUND).header(HttpHeaders.LOCATION, "http://www.baidu.com").build();
}
@Data
@AllArgsConstructor
public static class Foo {
private String name;
private int age;
}
}
发起POST请求
HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8080/demo").openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
//write header
connection.setRequestProperty("Content-Type", "application/json");
//write body
try (PrintWriter writer = new PrintWriter(connection.getOutputStream())) {
Map<String, String> foo = new HashMap<>();
foo.put("name", "HTTP");
foo.put("age", "18");
writer.write(JSONObject.toJSONString(foo));
writer.flush();
}
//read response
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} finally {
connection.disconnect();
}
发起GET请求
HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8080/demo/list?name=HTTP").openConnection();
connection.setRequestMethod("GET");
//write header
connection.setRequestProperty("Content-Type", "application/json");
//set timeout
connection.setConnectTimeout(1000 * 5);
connection.setReadTimeout(1000 * 10);
//connect
connection.connect();
int responseCode = connection.getResponseCode();
log.info("response code : {}", responseCode);
// read response
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} finally {
connection.disconnect();
}
错误处理
HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8080/demo/error").openConnection();
connection.setRequestMethod("GET");
//write header
connection.setRequestProperty("Content-Type", "application/json");
connection.connect();
BufferedReader reader;
try {
int responseCode = connection.getResponseCode();
if (responseCode == 200) {
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} else {
log.error("发生异常,code={}", responseCode);
reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
}
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
} finally {
connection.disconnect();
}
重定向处理
HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8080/demo/redirect").openConnection();
connection.setRequestMethod("GET");
//write header
connection.setRequestProperty("Content-Type", "application/json");
connection.connect();
//取消自动重定向
connection.setInstanceFollowRedirects(false);
int responseCode = connection.getResponseCode();
log.info("response code : {}", responseCode);
if (responseCode == 302) {
String location = connection.getHeaderField("Location");
URLConnection redirect = new URL(location).openConnection();
redirect.connect();
// read response
try (BufferedReader reader = new BufferedReader(new InputStreamReader(redirect.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} finally {
connection.disconnect();
}
}
核心API
- 发送请求体需要:setDoOutput(true)
- 设置请求头:setRequestProperty
- 获取请求头:getHeaderField
- 设置超时
- 连接超时:setConnectTimeout
- 读取超吃:setReadTimeout
- 获取状态码:getResponseCode
- 异常流:getErrorStream
总结
这里简单使用了HttpURLConnection作为Http客户端的实现,实现步骤比较繁琐,可读性也不是很友好,不过使用Java原生的类库,无侵入性,无其他依赖。