SpringBoot Controller保留@RequestBody参数时如何获取请求IP
在SpringBoot Controller中保留原有方法签名获取请求IP
有两种常用方案可以在不修改现有方法签名的前提下获取请求IP:
方案一:注入HttpServletRequest
直接在Controller类中注入HttpServletRequest对象,无需修改方法参数即可调用其API获取IP:
@RestController public class HelloController { // 注入HttpServletRequest @Autowired private HttpServletRequest request; @PostMapping("/coolendpointTWO") public String withRequestBody(@RequestBody MyPojo myPojo) { System.out.println("received object" + myPojo); //handle myPojo with my business logic // 获取客户端IP String ip = request.getRemoteAddr(); return "good: " + ip; } }
方案二:使用RequestContextHolder静态获取请求对象
如果不想注入HttpServletRequest,可以通过Spring提供的RequestContextHolder工具类静态获取当前请求的上下文,进而拿到请求对象:
@RestController public class HelloController { @PostMapping("/coolendpointTWO") public String withRequestBody(@RequestBody MyPojo myPojo) { System.out.println("received object" + myPojo); //handle myPojo with my business logic // 从上下文获取请求对象 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); String ip = request.getRemoteAddr(); return "good: " + ip; } }
注意:反向代理场景下的IP获取
如果你的服务部署在反向代理(如Nginx、Apache)之后,getRemoteAddr()拿到的会是代理服务器的IP,而非真实客户端IP。此时需要从请求头中读取转发的IP信息,可封装一个工具方法处理:
private String getClientIp(HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("X-Real-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } // 如果X-Forwarded-For有多个IP,取第一个非unknown的 if (ip != null && ip.contains(",")) { ip = ip.split(",")[0].trim(); } return ip; }
调用时直接替换request.getRemoteAddr()为getClientIp(request)即可。
内容的提问来源于stack exchange,提问作者PatPanda
相关产品推荐
相关产品推荐

