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

如何在Spring Boot控制器中获取客户端主机/域名信息

解决Spring Boot API获取调用方主机名及端口的问题

问题分析

你遇到的是后端服务间调用的标识问题:

  • Origin和Referer是浏览器专属请求头,RestTemplate这类后端HTTP客户端不会自动携带,所以API端获取不到是正常现象。
  • getRemoteAddr()返回的是客户端请求的IP(本地调用时通常是127.0.0.1),但默认拿不到调用方应用的固定端口(比如9000),因为RestTemplate发起请求时用的是临时随机端口,而非应用的服务端口。

可行解决方案

方案1:调用方主动携带自定义标识头(最可靠)

让每个调用API的Java应用在请求头中添加自定义的客户端信息,包含主机名和应用端口,API端直接读取该头即可。

调用方(RestTemplate)修改代码:

RestTemplate restTemplate1 = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

// 添加自定义客户端标识头
// 若为Spring Boot应用,可注入ServerProperties动态获取自身服务端口
String clientHost = InetAddress.getLocalHost().getHostName() + ":9000";
headers.add("X-Client-Identity", clientHost);

Map<String, String> map = new HashMap<>();
map.put("username", "test");
map.put("password", "test");
String jsonBody = new ObjectMapper().writeValueAsString(map);

HttpEntity<String> entity = new HttpEntity<>(jsonBody, headers);
ResponseEntity<String> response = restTemplate1.exchange(
    "http://localhost:8000/test", 
    HttpMethod.POST, 
    entity, 
    String.class
);

API端(控制器)读取标识:

@PostMapping("/test")
public String authenticateAndGetToken(HttpServletRequest httpServletRequest, @RequestBody Request request) {
    // 读取自定义客户端标识
    String clientIdentity = httpServletRequest.getHeader("X-Client-Identity");
    Log.info("调用方信息:" + clientIdentity);

    // 原有业务逻辑
    String errorMsg = "Invalid UserName";
    UserDetails userDetails = userInfoService.loadUserByUsername(request.getUsername());
    // ... 后续代码
}

方案2:通过远程IP+端口反查主机名(仅能获取请求临时端口)

如果不需要调用方的应用固定端口,仅需识别请求来源的主机和临时请求端口,可通过HttpServletRequest的远程信息结合IP反查实现:

@PostMapping("/test")
public String authenticateAndGetToken(HttpServletRequest httpServletRequest, @RequestBody Request request) {
    String clientIp = httpServletRequest.getRemoteAddr();
    int clientPort = httpServletRequest.getRemotePort();
    
    // 通过IP反查主机名
    String clientHostname = "";
    try {
        InetAddress addr = InetAddress.getByName(clientIp);
        clientHostname = addr.getHostName();
    } catch (UnknownHostException e) {
        clientHostname = clientIp; // 反查失败时用IP替代
    }
    
    String clientInfo = clientHostname + ":" + clientPort;
    Log.info("调用方请求信息:" + clientInfo);

    // 原有业务逻辑
    // ...
}

注意:此方案拿到的端口是RestTemplate发起请求时使用的临时端口,并非调用方应用的服务端口(9000),仅适用于识别请求来源主机,无法定位到具体应用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 00:00:05