Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Spring MVC控制器get call中提取IP地址?_Java_Spring Mvc_Ip Address - Fatal编程技术网

Java 如何在Spring MVC控制器get call中提取IP地址?

Java 如何在Spring MVC控制器get call中提取IP地址?,java,spring-mvc,ip-address,Java,Spring Mvc,Ip Address,我正在从事SpringMVC控制器项目,在该项目中,我正在从浏览器中进行一个GET URL调用- http://127.0.0.1:8080/testweb/processing?workflow=test&conf=20140324&dc=all 下面是我从浏览器拨打GET电话的url- http://127.0.0.1:8080/testweb/processing?workflow=test&conf=20140324&dc=all 下面是点击浏览器后调

我正在从事SpringMVC控制器项目,在该项目中,我正在从浏览器中进行一个GET URL调用-

http://127.0.0.1:8080/testweb/processing?workflow=test&conf=20140324&dc=all
下面是我从浏览器拨打GET电话的url-

http://127.0.0.1:8080/testweb/processing?workflow=test&conf=20140324&dc=all
下面是点击浏览器后调用的代码-

@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
    }
问题陈述:-

现在有没有办法,我可以从一些头提取IP地址?这意味着我想知道呼叫来自哪个IP地址,这意味着无论谁在URL上方呼叫,我都需要知道他们的IP地址。这可能吗?

解决方案是

@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
    }
HttpServletRequest
添加到方法定义中,然后使用Servlet API

Spring文档在

15.3.2.3支持的处理程序方法参数和返回类型


我来晚了,但这可能有助于寻找答案。通常
servletRequest.getRemoteAddr()
可以正常工作

在许多情况下,您的应用程序用户可能通过代理服务器访问您的web服务器,或者您的应用程序位于负载平衡器后面

因此,在这种情况下,您应该访问http头以获取用户的IP地址

e、 g.
String ipAddress=request.getHeader(“X-FORWARDED-FOR”)


希望这能有所帮助。

您可以从
RequestContextHolder
静态获取IP地址,如下所示:

HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
        .getRequest();

String ip = request.getRemoteAddr();

下面是Spring方式,在
@Controller
类中使用
自动连线的
请求bean:

@Autowired 
private HttpServletRequest request;

System.out.println(request.getRemoteHost());

我用这种方法来做这件事

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();
    }
}

将此方法放在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;
}

见下文。此代码适用于spring boot和spring boot+ApacheCxf/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());

:)

在我的例子中,我在应用程序前面使用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';
}
因此,在我的应用程序中,我得到了真实的用户ip,如下所示:

String clientIP = request.getHeader("X-Real-IP");

我将上面的代码与此代码结合起来,在大多数情况下都能工作。将从api获得的
HttpServletRequest请求
传递给方法

,感谢Koitoer的帮助。一个简单的问题,假设调用来自负载平衡器而不是特定的机器,那么这也可以工作吗?我想不是…不,但是,在负载均衡器中有一些配置可以发送IP,因为它们不存在,可能这是你的CaseChIP,可能负载均衡器可以在头文件中发送这些值,所以考虑使用HeTpServestRevest.GoeTead方法。但是除了HttpServletRequest还有其他方法。这是不推荐的。请注意,
X-Forwarded-For
通常是一个以逗号分隔的IP列表,链中的每个代理都会将它看到的远程地址添加到列表中。因此,一个好的实现通常会有一个可信代理列表,并在从右到左读取此标头时“跳过”这些ip。如何将ip地址获取为111.111.111.111/X请注意,例如,Tomcat有
RemoteIpValve
,它解析
X-Forwarded-For
标头并将其设置在
HttpServletRequest
上,因此,
servletRequest.getRemoteAddr()
返回正确的最终用户IP地址。在Spring Boot中,可以通过
server.tomcat.remote ip header=X-Forwarded-For
应用程序属性启用它。这可能会导致多线程并发使用控制器时出现问题。只能使用
@Autowired
将单例注入
@Controller
实例。否则,您必须在控制器类上使用
@Scope(BeanDefinition.Scope\u PROTOTYPE)
,以确保每个请求都生成控制器的新实例。这效率较低,但如果必须将某些内容作为属性注入控制器类,则这是一种变通方法。请尝试使用Spring AOP并处理HttpServletRequest。我在哪里使用它?
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 getIPFromRequest(HttpServletRequest request) {
        String ip = null;
        if (request == null) {
            if (RequestContextHolder.getRequestAttributes() == null) {
                return null;
            }
            request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        }

        try {
            ip = InetAddress.getLocalHost().getHostAddress();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (!StringUtils.isEmpty(ip))
            return ip;

        for (String header : IP_HEADER_CANDIDATES) {
            String ipList = request.getHeader(header);
            if (ipList != null && ipList.length() != 0 && !"unknown".equalsIgnoreCase(ipList)) {
                return ipList.split(",")[0];
            }
        }

        return request.getRemoteAddr();
    }