Java 如何在 Spring MVC 控制器获取调用中提取 IP 地址?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22877350/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to extract IP Address in Spring MVC Controller get call?
提问by john
I am working on Spring MVC controller project in which I am making a GET URL call from the browser -
我正在处理 Spring MVC 控制器项目,我正在从浏览器进行 GET URL 调用 -
Below is the url by which I am making a GET call from the browser -
以下是我从浏览器进行 GET 调用的网址 -
http://127.0.0.1:8080/testweb/processing?workflow=test&conf=20140324&dc=all
And below is the code in which the call comes after hitting at the browser -
下面是点击浏览器后调用的代码 -
@RequestMapping(value = "processing", method = RequestMethod.GET)
public @ResponseBody ProcessResponse processData(@RequestParam("workflow") final String workflow,
@RequestParam("conf") final String value, @RequestParam("dc") final String dc) {
System.out.println(workflow);
System.out.println(value);
System.out.println(dc);
// some other code
}
Problem Statement:-
问题陈述:-
Now is there any way, I can extract IP Address from some header? Meaning I would like to know from which IP Address, call is coming, meaning whoever is calling above URL, I need to know their IP Address. Is this possible to do?
现在有什么办法可以从某些标头中提取 IP 地址吗?这意味着我想知道呼叫来自哪个 IP 地址,这意味着无论谁在 URL 上呼叫,我都需要知道他们的 IP 地址。这是可能的吗?
采纳答案by Koitoer
The solution is
解决办法是
@RequestMapping(value = "processing", method = RequestMethod.GET)
public @ResponseBody ProcessResponse processData(@RequestParam("workflow") final String workflow,
@RequestParam("conf") final String value, @RequestParam("dc") final String dc, HttpServletRequest request) {
System.out.println(workflow);
System.out.println(value);
System.out.println(dc);
System.out.println(request.getRemoteAddr());
// some other code
}
Add HttpServletRequest request
to your method definition and then use the Servlet API
添加HttpServletRequest request
到您的方法定义,然后使用 Servlet API
Spring Documentation heresaid in
Spring文档在这里说
15.3.2.3 Supported handler method arguments and return types
15.3.2.3 支持的处理程序方法参数和返回类型
Handler methods that are annotated with @RequestMapping can have very flexible signatures.
Most of them can be used in arbitrary order (see below for more details).
Request or response objects (Servlet API). Choose any specific request or response type,
for example ServletRequest or HttpServletRequest
回答by sunitkatkar
I am late here, but this might help someone looking for the answer. Typically servletRequest.getRemoteAddr()
works.
我来晚了,但这可能有助于寻找答案的人。通常servletRequest.getRemoteAddr()
有效。
In many cases your application users might be accessing your web server via a proxy server or maybe your application is behind a load balancer.
在许多情况下,您的应用程序用户可能通过代理服务器访问您的 Web 服务器,或者您的应用程序可能位于负载均衡器之后。
So you should access the X-Forwarded-Forhttp header in such a case to get the user's IP address.
因此,在这种情况下,您应该访问X-Forwarded-Forhttp 标头以获取用户的 IP 地址。
e.g. String ipAddress = request.getHeader("X-FORWARDED-FOR");
例如 String ipAddress = request.getHeader("X-FORWARDED-FOR");
Hope this helps.
希望这可以帮助。
回答by Radouane ROUFID
You can get the IP address statically from the RequestContextHolder
as below :
您可以从RequestContextHolder
以下静态获取 IP 地址:
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
String ip = request.getRemoteAddr();
回答by Leon
Below is the Spring way, with autowired
request bean in @Controller
class:
下面是 Spring 的方式,autowired
在@Controller
类中使用请求 bean :
@Autowired
private HttpServletRequest request;
System.out.println(request.getRemoteHost());
回答by panser
I use such method to do this
我使用这种方法来做到这一点
public class HttpReqRespUtils {
private static final String[] IP_HEADER_CANDIDATES = {
"X-Forwarded-For",
"Proxy-Client-IP",
"WL-Proxy-Client-IP",
"HTTP_X_FORWARDED_FOR",
"HTTP_X_FORWARDED",
"HTTP_X_CLUSTER_CLIENT_IP",
"HTTP_CLIENT_IP",
"HTTP_FORWARDED_FOR",
"HTTP_FORWARDED",
"HTTP_VIA",
"REMOTE_ADDR"
};
public static String getClientIpAddressIfServletRequestExist() {
if (RequestContextHolder.getRequestAttributes() == null) {
return "0.0.0.0";
}
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
for (String header: IP_HEADER_CANDIDATES) {
String ipList = request.getHeader(header);
if (ipList != null && ipList.length() != 0 && !"unknown".equalsIgnoreCase(ipList)) {
String ip = ipList.split(",")[0];
return ip;
}
}
return request.getRemoteAddr();
}
}
回答by BaiJiFeiLong
Put this method in your BaseController:
将此方法放在您的 BaseController 中:
@SuppressWarnings("ConstantConditions")
protected String fetchClientIpAddr() {
HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getRequest();
String ip = Optional.ofNullable(request.getHeader("X-FORWARDED-FOR")).orElse(request.getRemoteAddr());
if (ip.equals("0:0:0:0:0:0:0:1")) ip = "127.0.0.1";
Assert.isTrue(ip.chars().filter($ -> $ == '.').count() == 3, "Illegal IP: " + ip);
return ip;
}
回答by Vagner Nogueira
See below. This code works with spring-boot and spring-boot + apache CXF/SOAP.
见下文。此代码适用于 spring-boot 和 spring-boot + apache CXF/SOAP。
// in your class RequestUtil
private static final String[] IP_HEADER_NAMES = {
"X-Forwarded-For",
"Proxy-Client-IP",
"WL-Proxy-Client-IP",
"HTTP_X_FORWARDED_FOR",
"HTTP_X_FORWARDED",
"HTTP_X_CLUSTER_CLIENT_IP",
"HTTP_CLIENT_IP",
"HTTP_FORWARDED_FOR",
"HTTP_FORWARDED",
"HTTP_VIA",
"REMOTE_ADDR"
};
public static String getRemoteIP(RequestAttributes requestAttributes)
{
if (requestAttributes == null)
{
return "0.0.0.0";
}
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
String ip = Arrays.asList(IP_HEADER_NAMES)
.stream()
.map(request::getHeader)
.filter(h -> h != null && h.length() != 0 && !"unknown".equalsIgnoreCase(h))
.map(h -> h.split(",")[0])
.reduce("", (h1, h2) -> h1 + ":" + h2);
return ip + request.getRemoteAddr();
}
//... in service class:
String remoteAddress = RequestUtil.getRemoteIP(RequestContextHolder.currentRequestAttributes());
:)
:)
回答by BaDr Amer
In my case, I was using Nginx in front of my application with the following configuration:
就我而言,我在我的应用程序前面使用了 Nginx,配置如下:
location / {
proxy_pass http://localhost:8080/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
add_header Content-Security-Policy 'upgrade-insecure-requests';
}
so in my application I get the real user ip like so:
所以在我的应用程序中,我得到了真正的用户 ip,如下所示:
String clientIP = request.getHeader("X-Real-IP");