当前位置: 首页 > 知识库问答 >
问题:

为什么只有在使用Spring RestTemplate执行调用时,externa web服务调用才会出错?

史阳晖
2023-03-14

我正在从事一个Spring项目,该项目实现了一个简单的控制台应用程序,该应用程序必须调用一个外部REST web服务,向其传递一个参数并从中获取响应。

此Web服务的调用是:

http://5.249.148.180:8280/GLIS_Registration/6

其中6是指定的ID。如果在浏览器中(或通过cURL工具)打开此地址,将获得预期的错误消息:

<?xml version="1.0" encoding="UTF-8"?>
<response>
    <sampleid>IRGC 100000</sampleid>
    <genus>Oryza</genus>
    <error>PGRFA sampleid [IRGC 100000], genus [Oryza] already registered for this owner</error>
</response>

这个错误消息是这个请求的预期响应,我也使用cURL工具正确地获取了它来执行请求。

所以我必须从我的Spring应用程序执行这个GET请求。

为此,我将这个getResponse()方法创建到一个RestClient类中:

@Service
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RestClient {

    RestTemplate restTemplate;
    String uriResourceRegistrationApi;

    public RestClient() {
        super();

        restTemplate = new RestTemplate();
        uriResourceRegistrationApi = "http://5.249.148.180:8280/GLIS_Registration/7";
    }

    public ResponseEntity<String> getResponse() {

        ResponseEntity<String> response = restTemplate.getForEntity(uriResourceRegistrationApi, String.class);
        return response;

    }
}

然后我从这个测试方法中调用这个方法

@Test
public void singleResourceRestTest() {
    System.out.println("singleResourceRestTest() START");

    ResponseEntity<String> result = restClient.getResponse();

    System.out.println("singleResourceRestTest() END");
}

但我经历了一个非常奇怪的行为,它发生的是:

1) 对我的外部web服务的调用似乎发生了(我从web服务日志中看到)。

2) web服务检索值为7的参数,但如果不执行来自浏览器或shell语句的请求,则似乎无法使用它:

curl -v http://5.249.148.180:8280/GLIS_Registration/7

但是现在,以这种方式调用,我的webservice(我不能发布代码,因为它是WSO2 ESB流)给我这个错误消息:

<200 OK,<?xml version="1.0" encoding="UTF-8"?>
<response>
    <error>Location information not correct</error>
    <error>At least one between &lt;genus> and &lt;cropname> is required</error>
    <error>Sample ID is required</error>
    <error>Date is required</error>
    <error>Creation method is required</error>
</response>,{Vary=[Accept-Encoding], Content-Type=[text/html; charset=UTF-8], Date=[Fri, 05 May 2017 14:07:09 GMT], Transfer-Encoding=[chunked], Connection=[keep-alive]}>

查看web服务日志,似乎使用RestTemplate执行调用时,使用检索到的ID=7执行数据库查询有一些问题。

我知道这看起来非常奇怪,你可以看到:“问题在于你的web服务,而不是Spring RestTemplate”。这只是部分正确,因为我实现了这个自定义方法,该方法执行一个低级Http GET调用,即callWsOldStyle()(放在前面的RestClient类中):

public void callWsOldStyle() {
    HttpURLConnection connection = null;
    BufferedReader reader = null;

    try {
        URL restAPIUrl = new URL("http://5.249.148.180:8280/GLIS_Registration/7");
        connection = (HttpURLConnection) restAPIUrl.openConnection();
        connection.setRequestMethod("GET");

        // Read the response
        reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        StringBuilder jsonData = new StringBuilder();
        String line;

        while ((line = reader.readLine()) != null) {
            jsonData.append(line);
        }


        System.out.println(jsonData.toString());
    }catch(Exception e) {
        e.printStackTrace();
    }
    finally {
    // Clean up
        IOUtils.closeQuietly(reader);
        if(connection != null)
            connection.disconnect();
    }
}

使用此方法而不是RestTemplate方法,效果很好,这行代码:

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

打印预期结果:

<?xml version="1.0" encoding="UTF-8"?><response><sampleid>IRGC 100005</sampleid><genus>Oryza</genus><error>PGRFA sampleid [IRGC 100005], genus [Oryza] already registered for this owner</error></response>

总结:

  • 从浏览器调用我的WS它工作。
  • 使用cURL调用我的WS。
  • 使用我的call WsOldStyle()方法调用我的WS是有效的。
  • 当我的WS收到并尝试处理请求时,使用使用RestTemboard的方法调用我的WS会出错。

那么,这个问题的原因是什么?我错过了什么?也许可以依靠一些错误的标题或类似的东西?

共有1个答案

唐健
2023-03-14

正如Pete所说,您收到了一个内部服务器错误(状态代码500),因此您应该检查此Rest服务的服务器端。

在任何情况下,您都可以对resttemplate

  • 创建一个组织。springframework。网状物客户RequestCallback对象,如果需要在请求中执行某些操作
  • 创建一个组织。springframework。网状物客户响应采集器

组织。springframework。网状物客户请求回调

public class SampleRequestCallBack implements RequestCallback
{

    @Override
    public void doWithRequest(ClientHttpRequest request) throws IOException
    {
    }

}

组织。springframework。网状物客户响应采集器

public class CustomResponseExtractor implements ResponseExtractor<String>
{
    private static final Logger logger = LoggerFactory.getLogger(CustomResponseExtractor.class.getName()); 
    @Override
    public String extractData(ClientHttpResponse response) throws IOException
    {

        try
        {
            String result = org.apache.commons.io.IOUtils.toString(response.getBody(), Charset.forName("UTF8"));
            if( logger.isInfoEnabled() )
            {
                logger.info("Response received.\nStatus code: {}\n Result: {}",response.getStatusCode().value(), result);
            }
            return result;
        }
        catch (Exception e)
        {
            throw new IOException(e);
        }
    }
}

REST模板调用

@Test
public void testStack()
{
    try
    {
        String url = "http://5.249.148.180:8280/GLIS_Registration/6";
        String response = restTemplate.execute(url, HttpMethod.GET, new SampleRequestCallBack(), new CustomResponseExtractor());;
        logger.info(response);
    }
    catch (Exception e)
    {
        logger.error("Errore", e);
    }
}

安杰洛

 类似资料:
  • 我有HTTPS web服务。我可以使用wsimport生成java类,但当我调用该服务时,我收到以下异常: 调用服务的类如下所示: 有人能帮忙吗。提前谢谢你。

  • 第二种情况有什么问题? 未捕获的TypeError:x.toLocaleUpperCase在HtmlButtoneElement的f(:2:14) 在:5:25 处不是函数。执行按钮。onclick

  • 问题内容: 在运行JUnit测试时,我似乎总是会遇到此错误: 蚀outOfMemoryError:堆空间 我已经用JConsole监视了Eclipse,并且堆内存的峰值大约为150MB。我已将堆内存设置为1GB。 启动Eclipse时,我使用以下参数: 有谁知道是什么原因导致此问题?它仅在运行JUnit测试时发生。 问题答案: Junit测试在与Eclipse IDE不同的vm中运行。因此,内存不

  • 我有一个ArrayList,它应该在包含0个以上对象时启动报警服务,在包含0个对象时停止报警服务。 这是报警服务类。 这是on Receive方法广播接收器类 问题是,即使调用了报警服务的onDestroy方法,通知也不会停止。 我错过什么了吗? 谢谢

  • 问题内容: 我有一个来自表单提交的简单ajax调用。当我调试时它可以工作,即弹出警报,但是在运行它时不起作用? 这对我来说似乎有点神秘。 问题答案: 如果您在表单的.submit()处理程序上运行ajax调用,则将触发 Ajax请求,但随后该表单将继续提交,从而刷新页面并且从不触发您的回调函数。 相反,您应该在Submit handler函数的末尾调用,以防止浏览器使用新的HTTP请求正常提交表单

  • 调用时,实际会执行什么操作? 将分配内存,复制字符串对象的内部数据并在新分配的内存中追加一个以null结尾的字符? 或者 在这个问题的答案的评论中有人说,C11要求为后面的分配一个额外的。因此,第二种选择似乎是可能的。 另一个人说,操作——例如迭代、串联和元素突变——不需要零终止符。除非将传递给需要以零结尾的字符串的函数,否则可以忽略该字符串。 为什么实现者通常让. data()和.c_str()