You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot调用外部API报错 如何通过另一控制器输出JSON数据

问题修复与实现方案

一、HTTP 500错误根因与修复

你当前的报错来自两个核心问题:

  • 声明的e_url是空字符串,调用外部API时没有有效地址直接发起请求必然抛出异常
  • 外部API返回的是单个JSON对象,并非JSON数组,用Object[].class作为返回类型接收会触发类型转换异常
    修复后的File1.java代码如下:
@RestController
@RequestMapping("/api")
public class Controller1 {
    // 建议将RestTemplate注入,不要每次方法调用都新建实例
    @Autowired
    private RestTemplate restTemplate;

    // 可以保留这个接口供内部调用,也可以直接把逻辑抽到Service层复用
    @GetMapping(value = "/test")
    public Map<String, Object> getExternalData() {
        String e_url = "你实际的外部API地址"; // 替换为真实API地址
        // 用Map接返回的单个JSON对象,也可以自定义对应的DTO类更规范
        return restTemplate.getForObject(e_url, Map.class);
    }
}

另外你需要先配置RestTemplate的Bean,在启动类或者配置类里添加:

@Bean
public RestTemplate restTemplate() {
    return new RestTemplate();
}

二、两个控制器联动实现方案

Spring Boot场景下不推荐用原生HttpServlet实现第二个控制器,也不需要强行通过请求跳转的方式连接两个控制器,推荐以下两种实现方式:

方案1:抽公共Service层(最推荐)

把调用外部API的逻辑单独抽到Service层,两个控制器都直接调用Service,不需要互相调用:

@Service
public class ExternalApiService {
    @Autowired
    private RestTemplate restTemplate;

    public Map<String, Object> getApiData() {
        String e_url = "你实际的外部API地址";
        return restTemplate.getForObject(e_url, Map.class);
    }
}

第二个控制器直接注入Service返回数据到页面即可,如果要保留你原来的HttpServlet写法,也可以直接在Servlet中注入Service:

// 如果用Spring Boot原生Controller写法
@Controller
@RequestMapping("/page")
public class Controller2 {
    @Autowired
    private ExternalApiService externalApiService;

    @PostMapping("/show")
    public void showData(HttpServletResponse response) throws IOException {
        response.setContentType("application/json;charset=utf-8");
        PrintWriter out = response.getWriter();
        Map<String, Object> data = externalApiService.getApiData();
        // Spring Boot自带Jackson依赖,直接转JSON字符串输出
        ObjectMapper objectMapper = new ObjectMapper();
        out.write(objectMapper.writeValueAsString(data));
        out.flush();
    }
}

方案2:Controller2直接调用Controller1的接口

如果你需要两个控制器完全解耦,也可以在Controller2中调用Controller1暴露的本地接口:

@Controller
@RequestMapping("/page")
public class Controller2 {
    @Autowired
    private RestTemplate restTemplate;

    @PostMapping("/show")
    public void showData(HttpServletResponse response) throws IOException {
        // 调用本地Controller1的接口地址,端口替换为你项目实际启动端口
        Map<String, Object> data = restTemplate.getForObject("http://localhost:8080/api/test", Map.class);
        response.setContentType("application/json;charset=utf-8");
        PrintWriter out = response.getWriter();
        ObjectMapper objectMapper = new ObjectMapper();
        out.write(objectMapper.writeValueAsString(data));
        out.flush();
    }
}

三、验证步骤

  1. 先替换外部API地址为真实可访问的地址,单独调用/api/test接口确认能正常返回JSON数据
  2. 用POST请求调用/page/show接口,确认可以正常返回JSON数据
  3. 如果需要用户端触发访问,只需要加一个POST表单提交到/page/show接口即可

内容的提问来源于stack exchange,提问作者s21s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 06:06:07