Solve the error problem of https request interface in Java

1. Solve the SSLException: Certificate for

1.1 Problem description

Recently, I am working on an intelligent Q&A customer service project, which is connected to the Yunwen interface. Then the Yunwen interface is connected using the https method. Before, it was always the http method. The sudden change caused an error when accessing the project. The error message is as shown in the title. It's an issue with the SSL certificate.

1.2 Solution

First solution:

When encountering a problem, first debug it and find that the error is caused by a tool class in the project. It seems that it is because there is no provision to use a default certificate. I don’t know if I understand it correctly. Anyway, after changing it according to the following code It's OK, but there will still be some other problems, which you can read below.

On the previous code, that is, the code that sends the http request, add the following two statements. Its main function is to configure HttpClient with SSL/TSL secure connection.

SSLConnectionSocketFactory scsf = new SSLConnectionSocketFactory(SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build(), NoopHostnameVerifier.INSTANCE);
httpclient = HttpClients.custom().setSSLSocketFactory(scsf).build();

The corrected code is as follows:

public static String doGet(String url, Map<String, Object> params) throws IOException {
    
      
        String apiUrl = url;  
        StringBuffer param = new StringBuffer();  
        int i = 0;  
        for (String key : params.keySet()) {
    
      
            if (i == 0)  
                param.append("?");  
            else  
                param.append("&");  
            param.append(key).append("=").append(params.get(key));  
            i++;  
        }  
        apiUrl += param;  
        String result = null;  
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
    
    
            SSLConnectionSocketFactory scsf = new SSLConnectionSocketFactory(SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build(), NoopHostnameVerifier.INSTANCE);
            httpclient = HttpClients.custom().setSSLSocketFactory(scsf).build();

            HttpGet httpPost = new HttpGet(apiUrl);  
            HttpResponse response = httpclient.execute(httpPost);

            HttpEntity entity = response.getEntity();  
            if (entity != null) {
    
      
                InputStream instream = entity.getContent();  
                result = IOUtils.toString(instream, "UTF-8");  
            }  
        } catch (Exception e) {
    
      
            e.printStackTrace();  
        }
        } finally {
    
    
        	if(httpclient!=null) {
    
    
        		httpclient.close();
        	}
        }
        return result;  
    }  

Second solution:

This solution was given by ChatGPT, and I have not verified its correctness.

import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;

import javax.net.ssl.SSLContext;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class HTTPSRequestExample {
    
    
    public static void main(String[] args) {
    
    
        try {
    
    
            // 创建自定义SSLContext
            SSLContext sslContext = SSLContextBuilder.create().loadTrustMaterial((chain, authType) -> true).build();

            // 创建SSLConnectionSocketFactory并禁用主机名验证
            SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);

            // 使用自定义SSLConnectionSocketFactory创建HttpClient
            CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslSocketFactory).build();

            // 创建要发送的GET请求
            HttpGet request = new HttpGet("https://example.com");

            // 发送请求并获取响应
            CloseableHttpResponse response = httpClient.execute(request);

            // 读取响应内容
            BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            String line;
            StringBuilder content = new StringBuilder();
            while ((line = reader.readLine()) != null) {
    
    
                content.append(line);
            }

            // 输出响应内容
            System.out.println("Response Content: " + content.toString());

        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if (response != null) {
    
    
                response.close();
            }
            if (httpClient != null) {
    
    
                httpClient.close();
            }
        }
    }
}

1.3 References

stackoverflow reference documentation

CSDN reference document

2. New problems arise

After modifying the code above, new problems will appear. Pictures, audios, and videos do not seem to work. F12 will report an error on the console, which seems to be related to the certificate. At the same time, the requested path will be changed to a local path. The error is reported as shown in the figure below.

image-20231106114630319

Guess you like

Origin blog.csdn.net/qq_43907505/article/details/134258974