首页 > 解决方案 > API 上 GET 调用的 403 状态

问题描述

请帮帮我。我刚刚开始开发并提出了一个与工作相关的有趣想法,通过 API 获取正确的关税来自动计算进口关税。

我正在尝试从 API 进行 GET 调用以计算进口关税。所以我看过一些关于 YT 的教程,这就是我想出的:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;

public class Main {

    private static HttpURLConnection connection;

    public static void main(String[] args) {
        // Method 1: java.net.httpURLconnection
        BufferedReader reader;
        String line;
        StringBuffer responseContent = new StringBuffer();

        try {
            //URL url = new URL("https://jsonplaceholder.typicode.com/albums"); THIS ONE WORKS
            URL url =  new URL("https://www.tariffnumber.com/api/v1/cnSuggest?term=85"); HERE 403
            //connection.setRequestProperty("User-agent", "UTF-8");
            connection = (HttpURLConnection) url.openConnection();

            //request set up
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);

            int status = connection.getResponseCode();

            System.out.println(status);

            if(status > 299) {
                reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
                while((line = reader.readLine()) != null) {
                    responseContent.append(line);
                }
                reader.close();
            } else {
                reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                while((line = reader.readLine()) != null) {
                    responseContent.append(line);
                }
                reader.close();
            }

            System.out.println(responseContent.toString());

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }   finally {
            connection.disconnect();
        }
    }

}

所以我的问题是,使用第一个 URL(https://jsonplaceholder.typicode.com/albums)一切正常。使用第二个 URL ( https://www.tariffnumber.com/api/v1/cnSuggest?term=85 ) 我得到状态 403。奇怪的是当我在 Postman 中使用相同的 URL 并执行 GET 请求时,我得到 200 OK 状态。我怎么可能在 Java 程序中获得 403 状态而在 Postman 中获得 200 OK?

顺便说一句,这个 API 有 litteraly 0 文档:

https://www.tariffnumber.com/services/api

先感谢您。

编辑:如果我添加

connection.setRequestProperty("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31");

设置新 URL 后,我在 Main.main(Main.java:53) 的线程“main”java.lang.NullPointerException 中得到一个异常

这是在代码行

connection.disconnect();

这很奇怪,因为如果我使用的 URL 都不起作用。所以添加这行代码稍后会给我一个错误。

编辑2:

在您的答案的帮助下修复了它,以下代码应该可以工作:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;

public class Main {

    public static void main(String[] args) throws IOException {
        // Method 1: java.net.httpURLconnection

        BufferedReader reader;
        String line;
        StringBuffer responseContent = new StringBuffer();
        HttpURLConnection connection = null;

        try {
            //URL url = new URL("https://jsonplaceholder.typicode.com/albums");
            URL url =  new URL("https://www.tariffnumber.com/api/v1/cnSuggest?term=85");
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestProperty("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31");

            //request set up
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);

            int status = connection.getResponseCode();

            System.out.println(status);

            if(status > 299) {
                reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
                while((line = reader.readLine()) != null) {
                    responseContent.append(line);
                }
                reader.close();
            } else {
                reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                while((line = reader.readLine()) != null) {
                    responseContent.append(line);
                }
                reader.close();
            }

            System.out.println(responseContent.toString());

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }   finally {
            connection.disconnect();
        }
    }

}

标签: java

解决方案


这个 API 似乎是一个非常糟糕的实现:它似乎没有任何文档,虽然它应该是免费的,但它没有解释为什么它会发送 403 Forbidden 状态码。

我进行了实验,它似乎拒绝了 Java 发送的默认 User-Agent 标头(我的机器上的 Java/1.8.0_212)。

例如,如果您作弊并发送 Chrome 的用户代理,它可以正常工作:

connection.setRequestProperty("User-agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31");

我们欧洲人纳税来提供这样的服务。您应该联系他们,以便他们提供体面的文档,并停止拒绝这样的用户代理。


推荐阅读