Estoy trabajando en el proyecto del controlador Spring MVC en el que estoy haciendo una llamada GET URL desde el navegador -
A continuación se muestra la URL con la que estoy haciendo una llamada GET desde el navegador:
http://127.0.0.1:8080/testweb/processing?workflow=test&conf=20140324&dc=all
Y a continuación se muestra el código en el que se produce la llamada después de presionar en el navegador:
@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
}
Planteamiento del problema:-
Ahora, ¿hay alguna forma de que pueda extraer la dirección IP de algún encabezado? Lo que significa que me gustaría saber de qué dirección IP viene la llamada, es decir, quienquiera que llame por encima de la URL, necesito saber su dirección IP. ¿Es posible hacer esto?
java
spring-mvc
ip-address
Juan
fuente
fuente
Respuestas:
La solucion es
@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 }
Agregue
HttpServletRequest request
a la definición de su método y luego use la API de ServletSpring Documentation aquí dicho en
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
fuente
Llego tarde aquí, pero esto podría ayudar a alguien que busque la respuesta. Normalmente
servletRequest.getRemoteAddr()
funciona.En muchos casos, los usuarios de su aplicación pueden estar accediendo a su servidor web a través de un servidor proxy o tal vez su aplicación esté detrás de un equilibrador de carga.
Por lo tanto, debe acceder al encabezado http X-Fordered-For en tal caso para obtener la dirección IP del usuario.
p.ej
String ipAddress = request.getHeader("X-FORWARDED-FOR");
Espero que esto ayude.
fuente
X-Forwarded-For
generalmente es una lista de ips separados por comas, con cada proxy en la cadena agregando la dirección remota que ve a la lista. Entonces, una buena implementación generalmente tendría una lista de proxies confiables y "omitir" esos ips al leer este encabezado de derecha a izquierda.Yo uso ese método para hacer esto
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(); } }
fuente
Puede obtener la dirección IP de forma estática de la
RequestContextHolder
siguiente manera:fuente
Pon este método en tu 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; }
fuente
Vea abajo. Este código funciona con spring-boot y 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());
:)
fuente
A continuación se muestra la forma de Spring, con un
autowired
bean de solicitud en la@Controller
clase:@Autowired private HttpServletRequest request; System.out.println(request.getRemoteHost());
fuente
@Controller
instancias usando@Autowired
. De lo contrario, debe usar@Scope(BeanDefinition.SCOPE_PROTOTYPE)
en la clase de controlador para asegurarse de que se realice una nueva instancia del controlador con cada solicitud. Esto es menos eficiente, pero es una solución si debe inyectar algo como una propiedad en la clase del controlador.En mi caso, estaba usando Nginx frente a mi aplicación con la siguiente configuración:
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'; }
así que en mi aplicación obtengo la IP del usuario real así:
String clientIP = request.getHeader("X-Real-IP");
fuente
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(); }
Combino el código anterior para que este código funcione en la mayoría de los casos. Pasa lo
HttpServletRequest request
que obtienes de la api al métodofuente