Java 如何从web服务器检索图像(图像/png标题)
我有一个带有PHP脚本的web服务器,该脚本将随机图像存储在服务器上。此响应直接是具有以下标题的图像:Java 如何从web服务器检索图像(图像/png标题),java,Java,我有一个带有PHP脚本的web服务器,该脚本将随机图像存储在服务器上。此响应直接是具有以下标题的图像: HTTP/1.1 200 OK Date: Mon, 20 Jan 2020 12:10:05 GMT Server: Apache/2.4.29 (Ubuntu) Expires: Mon, 1 Jan 2099 00:00:00 GMT Last-Modified: Mon, 20 Jan 2020 12:10:05 GMT Cache-Control: no-store, no-cach
HTTP/1.1 200 OK
Date: Mon, 20 Jan 2020 12:10:05 GMT
Server: Apache/2.4.29 (Ubuntu)
Expires: Mon, 1 Jan 2099 00:00:00 GMT
Last-Modified: Mon, 20 Jan 2020 12:10:05 GMT
Cache-Control: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 971646
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: image/png
如您所见,服务器直接向我回复MIME png文件类型。现在我想从JAVA程序中检索这个图像。我已经有了一个允许我从http请求中读取文本的代码,但是如何从web保存图像呢
public class test {
// one instance, reuse
private final HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.build();
public static void main(String[] args) throws Exception {
test obj = new test();
System.out.println("Testing 1 - Send Http POST request");
obj.sendPost();
}
private void sendPost() throws Exception {
// form parameters
Map<Object, Object> data = new HashMap<>();
data.put("arg", "value");
HttpRequest request = HttpRequest.newBuilder()
.POST(buildFormDataFromMap(data))
.uri(URI.create("url_here"))
.setHeader("User-Agent", "Java 11 HttpClient Bot") // add request header
.header("Content-Type", "application/x-www-form-urlencoded")
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
// print status code
System.out.println(response.statusCode());
// print response body
System.out.println(response.headers());
try {
saveImage(response.body(), "path/to/file.png");
}
catch(IOException e) {
e.printStackTrace();
}
}
public static void saveImage(String image, String destinationFile) throws IOException {
//What to write here ?
}
private static HttpRequest.BodyPublisher buildFormDataFromMap(Map<Object, Object> data) {
var builder = new StringBuilder();
for (Map.Entry<Object, Object> entry : data.entrySet()) {
if (builder.length() > 0) {
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 HttpRequest.BodyPublishers.ofString(builder.toString());
}
公共类测试{
//一个例子,重用
私有最终HttpClient HttpClient=HttpClient.newBuilder()
.version(HttpClient.version.HTTP_2)
.build();
公共静态void main(字符串[]args)引发异常{
测试对象=新测试();
System.out.println(“测试1-发送Http POST请求”);
obj.sendPost();
}
私有void sendPost()引发异常{
//形状参数
映射数据=新的HashMap();
数据。put(“arg”、“value”);
HttpRequest请求=HttpRequest.newBuilder()
.POST(buildFormDataFromMap(数据))
.uri(uri.create(“url\u here”))
.setHeader(“用户代理”,“Java 11 HttpClient Bot”)//添加请求头
.header(“内容类型”、“应用程序/x-www-form-urlencoded”)
.build();
HttpResponse response=httpClient.send(请求,HttpResponse.BodyHandlers.ofString());
//打印状态代码
System.out.println(response.statusCode());
//打印响应体
System.out.println(response.headers());
试一试{
saveImage(response.body(),“path/to/file.png”);
}
捕获(IOE异常){
e、 printStackTrace();
}
}
公共静态void saveImage(字符串图像,字符串destinationFile)引发IOException{
//在这里写什么?
}
私有静态HttpRequest.BodyPublisher buildFormDataFromMap(地图数据){
var builder=新的StringBuilder();
for(Map.Entry:data.entrySet()){
如果(builder.length()>0){
建筑商。追加(“&”);
}
append(URLEncoder.encode(entry.getKey().toString(),StandardCharsets.UTF_8));
生成器。追加(“=”);
append(URLEncoder.encode(entry.getValue().toString(),StandardCharsets.UTF_8));
}
返回HttpRequest.bodypublisher.ofString(builder.toString());
}
谢谢您的回复。试试这个:
public static void saveImage(String imageUrl, String destinationFile) throws IOException {
URL url = new URL(imageUrl);
try(InputStream is = url.openStream();
OutputStream os = new FileOutputStream(destinationFile)){
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
}catch(IOException e){
throw e;
}
}
我实际上编写了自己的Http客户端,它是名为MgntUtils的开源Java库的一部分,允许您读取文本和二进制响应。您的代码如下所示:
HttpClient client = new HttpClient();
client.setContentType("application/json; charset=utf-8"); //set any appropriate content type (of the input if you send any information from the client to the server)
client.setRequestProperty("Authorization", "Bearer ey..."); // this is just an example of how to set any header if you need. You might not need to set any additional headers
ByteBuffer buff = client.sendHttpRequestForBinaryResponse("http://example.com/image",HttpMethod.POST, "bla bla"); //This is example of invoking method POST with some input data "bla bla", third parameter is not mandatory if you have no data to pass
ByteBuffer buff1 = client.sendHttpRequestForBinaryResponse("http://example.com/image",HttpMethod.GET); //This is an example of invoking GET method
我和其他一些人使用了这个库,它使用简单,工作良好。该库可以作为Maven工件从GitHub获得,包括源代码和JavaDoc JavaDoc for HttpClient类只是一个2c,但除非服务器以Base64编码字符串的形式发送图像,否则最简单的方法是将图像作为一个字节数组,并将其写入文件。使用输入流下载任何文件类型以获取更多信息,请参阅本文。非常感谢@Nazimch您解决了我的问题,我无法使用它,因为我需要一个带有参数的POST请求查看:
//以InputStream HttpResponse response=client的形式接收响应正文。发送(request,BodyHandlers.ofInputStream());
然后将流写入文件。非常感谢@MarcStröbel您解决了我的问题。