获取我';我正在用Java写东西。在完成以下文档后,请求仍然失败

获取我';我正在用Java写东西。在完成以下文档后,请求仍然失败,java,http,ssl,http-headers,Java,Http,Ssl,Http Headers,我正在创建一个电子商务网站,我计划使用的其中一个直运商提供了一个api,可用于自动下单和跟踪订单。即使他们有几种语言(PHP、Python、Ruby、Node)的客户机,但他们还没有Java的客户机,所以我决定编写自己的客户机。我正在尝试测试它,但我一直得到这个错误 Hostname in certificate didn't match: <api.theprintful.com> != <behappy.me> OR <behappy.me> OR <

我正在创建一个电子商务网站,我计划使用的其中一个直运商提供了一个api,可用于自动下单和跟踪订单。即使他们有几种语言(PHP、Python、Ruby、Node)的客户机,但他们还没有Java的客户机,所以我决定编写自己的客户机。我正在尝试测试它,但我一直得到这个错误

Hostname in certificate didn't match: <api.theprintful.com> != <behappy.me> OR <behappy.me> OR <www.behappy.me>
我已经按照指示做了

//constructor that is used to make the object
public ProductsRequest(String apiKey)
{
    super();
    this.apiKey = apiKey;
    this.encodedApiKey = codec.encodeBase64String(apiKey.getBytes());
}

//function that is used to call the api
public List<Product> getAllProductList(String path)
{
    //the list of products that will be returned
    List<Product> returnedProducts = null;

    //set the endpoint that will be used to get the list of products
    httpGet = new HttpGet(path);
    String basicString = "Basic "+this.encodedApiKey;
    httpGet.addHeader("Authorization",basicString.substring(0,basicString.length()-2));

    try
    {
        response = httpClient.execute(httpGet);
        if(response.getStatusLine().getStatusCode() == 200)
        {
            entity = response.getEntity();
            jsonResponse = EntityUtils.toString(entity);
            Type listType = new TypeToken<List<Product>>(){}.getType();
            JsonNode root = mapper.readTree(jsonResponse);
            ArrayNode products = (ArrayNode) root.path("result");
            returnedProducts = (List<Product>) gson.fromJson(products.toString(),listType);
        }
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }

    return returnedProducts;
}
//用于生成对象的构造函数
公共产品请求(字符串apiKey)
{
超级();
this.apiKey=apiKey;
this.encodedApiKey=codec.encodeBase64String(apiKey.getBytes());
}
//用于调用api的函数
公共列表getAllProductList(字符串路径)
{
//将退回的产品列表
List returnedProducts=null;
//设置将用于获取产品列表的端点
httpGet=新的httpGet(路径);
字符串basicString=“Basic”+this.encodedApiKey;
httpGet.addHeader(“授权”,basicString.substring(0,basicString.length()-2));
尝试
{
response=httpClient.execute(httpGet);
if(response.getStatusLine().getStatusCode()==200)
{
entity=response.getEntity();
jsonResponse=EntityUtils.toString(实体);
类型listType=newTypeToken(){}.getType();
JsonNode root=mapper.readTree(jsonResponse);
ArrayNode产品=(ArrayNode)root.path(“结果”);
returnedProducts=(List)gson.fromJson(products.toString(),listType);
}
}
捕获(IOE异常)
{
e、 printStackTrace();
}
退货产品;
}
我不明白为什么我会犯这个错误。我试着给公司的开发团队发电子邮件,他们建议我尝试创建一个没有连接到任何电子商务软件的假商店,我可以用它进行测试,但他们说他们这方面一切都很好。我试着按照那个建议去做,但还是犯了同样的错误

我在Stackoverflow上发现了一个线程,看起来有人也有类似的问题。我只是想知道为什么我必须在Java中这样做,而其他语言中的其他客户机库都不必经历这个过程

据我所知,我正在按照文档所说的方式对所有内容进行编码,并且正确设置了标题。我需要使用不同的库吗

我目前正在使用ApacheCommons编解码器

<dependency>
      <groupId>commons-codec</groupId>
      <artifactId>commons-codec</artifactId>
      <version>1.4</version>
  </dependency>

通用编解码器
通用编解码器
1.4
和apachehttp组件

<dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpclient</artifactId>
      <version>4.3.2</version>
  </dependency>

org.apache.httpcomponents
httpclient
4.3.2

我试着用另一种语言运行该公司的一个客户端库中的示例,一切都正常工作。我知道我的代码有问题,而不是他们的SSL证书有问题,但我不知道是什么问题。

您是通过SSL连接的吗?i、 您的路径是否以“”开头?如果是这样的话,那么我认为现在发生的是,他们的SSL证书是为“api.theprintful.com”颁发的。为了防止中间人攻击,SSL客户端应该检查他们从服务器获得的证书是否真的是为相关服务器颁发的,请参阅。在您的情况下,此检查失败并导致您看到的异常。这与您的身份验证无关,您可能做的一切都是正确的,他们看到正确的请求,但您的一方在错误的证书上发出刺耳的声音

你能做些什么来解决这个问题

  • 请他们提供正确的证书。这是最简单、最好的解决方案。不幸的是,这需要他们方面的合作,你可能得到,也可能得不到
  • 伪造您自己的DNS,也就是说,在主机文件中添加一个条目,将api.theprintful.com指向www.behappy.me的IP地址。这是我的建议
  • 通过提供空HostnameVeriier来抑制主机名检查。这在上面的同一个线程中指出,并且可以在不干扰任何外部设置的情况下完成。但请确保,我的意思是绝对确保在将代码转移到生产环境之前删除该变通方法,否则

  • 您的服务器正在使用服务器名称指示来显示不同的证书,具体取决于您请求的名称(这对于在同一IP地址和端口上承载具有SSL/TLS的多个证书是必要的)

    您可以通过以下方式进行检查:

    openssl s_client -connect api.theprintful.com:443 -servername api.theprintful.com
    

    (并且仅在客户端,计划为Java8提供服务器端支持)

    当使用
    HttpsURLConnection
    时,使用Java 7的应用程序应该自动为您执行此操作

    这个。您应该确保您确实在使用版本4.3.2和Java 7。对于版本4.3.1(即使是Java 7)或Java 6上的4.3.2,以下操作将失败:

    CloseableHttpClient httpClient = HttpClients.createDefault();
    HttpGet httpGet = new HttpGet("https://sni.velox.ch/");
    HttpResponse response = httpClient.execute(httpGet);
    

    我使用的公司经营着两个不同的网站。一个是printful.com,另一个是behappy.me。printful就是提供api的那个。对于证书,我需要做什么。我没有,在他们的文档中也没有关于使用的信息。提供正确的证书是他们的工作。在www.example.com上设置SSL服务器的任何人都必须确保提供为“”颁发的证书。也许他们想通过只获得一个证书来省钱,也许这只是他们的一个简单的错误。好吧,我又试着给开发团队发了一封电子邮件。他们第一次反应很好,所以我猜这次也会。对我来说,尝试一下你上面的建议还有意义吗?我宁愿让他们修复他们的服务器,也不愿让他们在我这边解决这个问题。当然,如果他们不这样做,你就别无选择。我下载并安装了node,以测试他们的node客户端是否可以工作。它没有任何问题。这绝对是我在Java c中正在做的事情
    openssl s_client -connect api.theprintful.com:443
    
    CloseableHttpClient httpClient = HttpClients.createDefault();
    HttpGet httpGet = new HttpGet("https://sni.velox.ch/");
    HttpResponse response = httpClient.execute(httpGet);