Ich arbeite an einem Spring MVC Controller-Projekt, in dem ich einen GET URL-Aufruf vom Browser aus mache.
Unten ist die URL, über die ich einen GET-Anruf vom Browser aus tätige -
http://127.0.0.1:8080/testweb/processing?workflow=test&conf=20140324&dc=all
Und unten ist der Code, in dem der Anruf nach dem Drücken auf den Browser kommt -
@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
}
Problemstellung:-
Gibt es eine Möglichkeit, die IP-Adresse aus einem Header zu extrahieren? Das heißt, ich möchte wissen, von welcher IP-Adresse der Anruf kommt, dh wer über der URL anruft, muss seine IP-Adresse kennen. Ist das möglich?
java
spring-mvc
ip-address
John
quelle
quelle
Antworten:
Die Lösung ist
@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 }
Fügen Sie
HttpServletRequest request
Ihrer Methodendefinition hinzu und verwenden Sie dann die Servlet-APIFrühlingsdokumentation hier gesagt in
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
quelle
Ich bin spät dran, aber das könnte jemandem helfen, nach der Antwort zu suchen. Funktioniert normalerweise
servletRequest.getRemoteAddr()
.In vielen Fällen greifen Benutzer Ihrer Anwendung möglicherweise über einen Proxyserver auf Ihren Webserver zu, oder Ihre Anwendung befindet sich hinter einem Load Balancer.
In einem solchen Fall sollten Sie auf den X-Forwarded-For http-Header zugreifen , um die IP-Adresse des Benutzers abzurufen.
z.B
String ipAddress = request.getHeader("X-FORWARDED-FOR");
Hoffe das hilft.
quelle
X-Forwarded-For
es sich im Allgemeinen um eine durch Kommas getrennte Liste von IPs handelt, wobei jeder Proxy in der Kette die entfernte Adresse, die er sieht, zur Liste hinzufügt. Eine gute Implementierung würde also im Allgemeinen eine Liste vertrauenswürdiger Proxys haben und diese IPs "überspringen", wenn dieser Header von rechts nach links gelesen wird.Ich benutze eine solche Methode, um dies zu tun
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(); } }
quelle
Sie können die IP-Adresse statisch
RequestContextHolder
wie folgt abrufen :quelle
Fügen Sie diese Methode in Ihren BaseController ein:
@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; }
quelle
Siehe unten. Dieser Code funktioniert mit Spring-Boot und 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());
:) :)
quelle
Unten ist der Frühlingsweg mit
autowired
Anforderungsbohne in der@Controller
Klasse:@Autowired private HttpServletRequest request; System.out.println(request.getRemoteHost());
quelle
@Controller
Instanzen mit injiziert werden@Autowired
. Andernfalls müssen Sie@Scope(BeanDefinition.SCOPE_PROTOTYPE)
die Controller-Klasse verwenden, um sicherzustellen, dass bei jeder Anforderung eine neue Instanz des Controllers erstellt wird. Dies ist weniger effizient, stellt jedoch eine Problemumgehung dar, wenn Sie der Controller-Klasse etwas als Eigenschaft hinzufügen müssen.In meinem Fall habe ich Nginx vor meiner Anwendung mit der folgenden Konfiguration verwendet:
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 bekomme ich in meiner Anwendung die echte Benutzer-IP wie folgt:
String clientIP = request.getHeader("X-Real-IP");
quelle
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(); }
Ich kombiniere den obigen Code mit dieser Code-Arbeit für die meisten Fälle. Übergeben
HttpServletRequest request
Sie das, was Sie von der API erhalten, an die Methodequelle