Я работаю над проектом контроллера Spring MVC, в котором я выполняю вызов URL-адреса GET из браузера -
Ниже приведен URL-адрес, по которому я выполняю вызов GET из браузера -
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-адрес. Возможно ли это сделать?
java
spring-mvc
ip-address
Джон
источник
источник
Ответы:
Решение
@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 request
в определение вашего метода, а затем используйте API сервлетовДокументация Spring здесь сказано в
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
источник
Я здесь опаздываю, но это может помочь кому-то найти ответ. Обычно
servletRequest.getRemoteAddr()
работает.Во многих случаях пользователи вашего приложения могут обращаться к вашему веб-серверу через прокси-сервер или ваше приложение находится за балансировщиком нагрузки.
Таким образом, в таком случае вы должны получить доступ к HTTP-заголовку X-Forwarded-For, чтобы получить IP-адрес пользователя.
например
String ipAddress = request.getHeader("X-FORWARDED-FOR");
Надеюсь это поможет.
источник
X-Forwarded-For
обычно это список IP-адресов, разделенных запятыми, где каждый прокси в цепочке добавляет в список удаленный адрес, который он видит. Таким образом, хорошая реализация обычно имеет список доверенных прокси и пропускает эти IP-адреса при чтении этого заголовка справа налево.Я использую такой метод для этого
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(); } }
источник
Вы можете получить статический IP-адрес, как показано
RequestContextHolder
ниже:источник
Поместите этот метод в свой 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 + 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());
:)
источник
Ниже приведен способ Spring с
autowired
компонентом запроса в@Controller
классе:@Autowired private HttpServletRequest request; System.out.println(request.getRemoteHost());
источник
@Controller
экземпляры с использованием@Autowired
. В противном случае вы должны использовать@Scope(BeanDefinition.SCOPE_PROTOTYPE)
класс контроллера, чтобы гарантировать создание нового экземпляра контроллера с каждым запросом. Это менее эффективно, но это обходной путь, если вам нужно добавить что-то в качестве свойства в класс контроллера.В моем случае я использовал 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");
источник
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(); }
Я комбинирую приведенный выше код с этим кодом, работающим в большинстве случаев. Передайте полученное
HttpServletRequest request
от api методуисточник