使用HttpURLConnection发起HTTP请求

技术公众号: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 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 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原生的类库,无侵入性,无其他依赖。

参考

  • https://www.baeldung.com/java-http-request

你可能感兴趣的:(使用HttpURLConnection发起HTTP请求)