URL与URI
统一资源定位符(Uniform Resource Locator,URL)
统一资源标识符(Uniform Resource Identifier,URI)
URI类并不包含任何用于访问资源的方法,它的唯一作用就是解析。
但是,URL 类可以打开一个连接到资源的流。因此,URL类只能作用于那些 Java类库知道该如何处理的模式,例如 http∶、https∶、ftp∶、本地文件系统(file∶)和JAR文件(jar∶)。
URI类的作用之一是解析标识符并将它分解成各种不同的组成部分。
getScheme
getSchemeSpecificPart
getAuthority
getUsrInfo
getHost
getPort
getPath
public class URLDemo {
@SneakyThrows
public static void main(String[] args) {
URL url = new URL("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1496836692581&di=d5609e04e9f78f50dc2103e825e1e4d9&imgtype=0&src=http%3A%2F%2Fbpic.ooopic.com%2F15%2F57%2F11%2F15571198-c622e0f5ad9464916824bee7d3b8bfe1-3.jpg");
//把统一资源定位器转换为流对象
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
@Cleanup BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
@Cleanup BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("c:\\yali.jpg"));
byte[] bytes = new byte[1024];
int len = -1;
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();
}
System.out.println("下载成功");
}
}
URLConnection
- 调用URL类中的 openConnection方法获得 URLConnection 对象;
URLConnection connection = url.openConnection();
- 使用以下方法来设置任意的请求属性∶
setDoInput setDo0utput
setIfNodifiedSince
setUseCaches
setAllowUserInteraction
setRequestProperty
setConnectTimeout
setReadTimeout
调用 connect 方法连接远程资源∶connection.connect();
getHeaderFieldKey 和 getHeaderField这两个方法枚举了消息头的所有字段。
getHeaderFields 方法返回一个包,含了消息头中所有字段的标准Map 对象。
getContentType
getContentLength
getContentEncoding
getDate
getExpiration
getLastModified
最后,访问资源数据。使用 getInputStream方法获取一个输入流用以读取信息
httpClient java11
public class Java11HttpClient {
static HttpClient httpClient;
static HttpClient asynchttpClient;
static HttpClient jsonhttpClient;
@BeforeAll
public static void setHttpClient(){
httpClient = HttpClient.newHttpClient();
ExecutorService executor = Executors.newCachedThreadPool();
asynchttpClient = HttpClient.newBuilder().executor(executor).build();
}
/**
* get
*/
@Test
public void getTest() throws URISyntaxException, IOException, InterruptedException, ExecutionException {
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(new URI("https://www.cnblogs.com/pinlantu/p/11042476.html"))
.header("Accept-Language", "zh-CN")
.GET()
.build();
HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
int i = httpResponse.statusCode();
HttpClient.Version version = httpResponse.version();
String body = httpResponse.body();
/*
异步get
*/
CompletableFuture<HttpResponse<String>> httpResponseCompletableFuture = asynchttpClient.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofString());
String body1 = httpResponseCompletableFuture.get().body();
}
/**
* post
*/
@Test
public void postTest() throws URISyntaxException, IOException, InterruptedException {
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(new URI("http://www.w3school.com.cn/demo/demo_form.asp"))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString("name1=value1&name2=value2", StandardCharsets.UTF_8))
.build();
HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
String body = httpResponse.body();
System.out.println(body);
}
/**
* 并发请求
*/
@Test
public void bingfa(){
HttpClient client = HttpClient.newHttpClient();
List<String> urls = List.of("http://www.baidu.com","http://www.alibaba.com/","http://www.tencent.com");
List<HttpRequest> requests = urls.stream()
.map(url -> HttpRequest.newBuilder(URI.create(url)))
.map(HttpRequest.Builder::build)
.toList();
List<CompletableFuture<HttpResponse<String>>> futures = requests.stream()
.map(request -> client.sendAsync(request, HttpResponse.BodyHandlers.ofString()))
.toList();
futures.forEach(e -> e.whenComplete((resp,err) -> {
if(err != null){
err.printStackTrace();
}else{
System.out.println(resp.body());
System.out.println(resp.statusCode());
}
}));
CompletableFuture.allOf(futures
.toArray(CompletableFuture<?>[]::new))
.join();
}
}
BodyPublisher
class MoreBodyPublishers {
private static Map<Character, String> replacements = Map.of('\b', "\\b", '\f', "\\f",
'\n', "\\n", '\r', "\\r", '\t', "\\t", '"', "\\\"", '\\', "\\\\");
/**
* Url 参数处理 参数处理
*/
public static BodyPublisher ofFormData(Map<Object, Object> data) {
var first = true;
var builder = new StringBuilder();
for (Map.Entry<Object, Object> entry : data.entrySet()) {
if (first) {
first = false;
} else {
builder.append("&");
}
builder.append(URLEncoder.encode(entry.getKey().toString(),
StandardCharsets.UTF_8));
builder.append("=");
builder.append(URLEncoder.encode(entry.getValue().toString(),
StandardCharsets.UTF_8));
}
return BodyPublishers.ofString(builder.toString());
}
private static byte[] bytes(String s) {
return s.getBytes(StandardCharsets.UTF_8);
}
public static BodyPublisher ofMimeMultipartData(Map<Object, Object> data, String boundary)
throws IOException {
var byteArrays = new ArrayList<byte[]>();
byte[] separator = bytes("--" + boundary + "\nContent-Disposition: form-data; name=");
for (Map.Entry<Object, Object> entry : data.entrySet()) {
byteArrays.add(separator);
if (entry.getValue() instanceof Path) {
var path = (Path) entry.getValue();
String mimeType = Files.probeContentType(path);
byteArrays.add(bytes("\"" + entry.getKey() + "\"; filename=\"" + path.getFileName()
+ "\"\nContent-Type: " + mimeType + "\n\n"));
byteArrays.add(Files.readAllBytes(path));
} else {
byteArrays.add(bytes("\"" + entry.getKey() + "\"\n\n" + entry.getValue() + "\n"));
}
}
byteArrays.add(bytes("--" + boundary + "--"));
return BodyPublishers.ofByteArrays(byteArrays);
}
public static BodyPublisher ofSimpleJSON(Map<Object, Object> data) {
var builder = new StringBuilder();
builder.append("{");
var first = true;
for (Map.Entry<Object, Object> entry : data.entrySet()) {
if (first) {
first = false;
} else {
builder.append(",");
}
builder.append(jsonEscape(entry.getKey().toString())).append(": ")
.append(jsonEscape(entry.getValue().toString()));
}
builder.append("}");
return BodyPublishers.ofString(builder.toString());
}
private static StringBuilder jsonEscape(String str) {
var result = new StringBuilder("\"");
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
String replacement = replacements.get(ch);
if (replacement == null) {
result.append(ch);
} else {
result.append(replacement);
}
}
result.append("\"");
return result;
}
}
public class HttpClientTest {
public static void main(String[] args)
throws IOException, URISyntaxException, InterruptedException {
}
public static String doPost(String url, String contentType, Map<Object, Object> data)
throws IOException, URISyntaxException, InterruptedException {
HttpClient client = HttpClient.newBuilder()
.followRedirects(HttpClient.Redirect.ALWAYS).build();
BodyPublisher publisher = null;
if (contentType.startsWith("multipart/form-data")) {
String boundary = contentType.substring(contentType.lastIndexOf("=") + 1);
publisher = MoreBodyPublishers.ofMimeMultipartData(data, boundary);
} else if (contentType.equals("application/x-www-form-urlencoded")) {
publisher = MoreBodyPublishers.ofFormData(data);
} else {
contentType = "application/json";
publisher = MoreBodyPublishers.ofSimpleJSON(data);
}
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI(url))
.header("Content-Type", contentType)
.POST(publisher)
.build();
HttpResponse<String> response
= client.send(request, HttpResponse.BodyHandlers.ofString());
return response.body();
}
}