
能力说明:
了解变量作用域、Java类的结构,能够创建带main方法可执行的java应用,从命令行运行java程序;能够使用Java基本数据类型、运算符和控制结构、数组、循环结构书写和运行简单的Java程序。
暂时未有相关云产品技术能力~
阿里云技能认证
详细说明1.ActiveMQ官网链接:http://activemq.apache.org/①选择Download②选择ActiveMQ 5.15.8 Release需要注意的是:ActiveMQ 5.15.8所需Jdk版本最低为1.8,修改具体请看Change Log③复制下载链接 cd /usr/local wget http://www.apache.org/dyn/closer.cgi?filename=/activemq/5.15.8/apache-activemq-5.15.8-bin.tar.gz&action=download 会发现,文件无法下载,我尝试着关闭防火墙,重启network,无效(因为响应是200)因为URL中有一个"&"需要转义"&" cd /usr/local wget http://www.apache.org/dyn/closer.cgi?filename=\/activemq\/5.15.8\/apache-activemq-5.15.8-bin.tar.gz\&action=download wget的命名规则是取最后一个"/"后面的内容,文件重命名 mv ./closer.cgi\?filename\=%2Factivemq%2F5.15.8%2Fapache-activemq-5.15.8-bin.tar.gz\&action\=download ./apache-activemq-5.15.8-bin.tar.gz 2.解压apache-activemq-5.15.8-bin.tar.gz tar -xzvf ./apache-activemq-5.15.8-bin.tar.gz 3.启动ActiveMQ①ActiveMQ内置了jetty Web容器,jetty的相关配置在jetty.xml中 vim /usr/local/apache-activemq-5.15.8/conf/jetty.xml ②ActiveMQ的配置文件 vim /usr/local/apache-activemq-5.15.8/conf/activemq.xml ③ActiveMQ管控台的用户名密码配置 vim /usr/local/apache-activemq-5.15.8/conf/jetty-realm.properties ④进入bin目录,启动ActiveMQ /usr/local/apache-activemq-5.15.8/bin/activemq start 查看端口61616是否开启 netstat -an|grep 61616 netstat -an|grep 8161 ⑤登录ActiveMQ管控台:http://192.168.0.115:8161/admin/4.编写程序①消息发送方(生产者): package activemq; import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; public class ActiveMQ_Sender { public static void main(String[] args) throws JMSException { //1.建立ConnectionFactory工厂对象,需要填入用户名、密码以及要连接的地址,均使用默认即可, // 默认端口为"tcp://localhost:61616" ConnectionFactory connectionFactory = new ActiveMQConnectionFactory( ActiveMQConnectionFactory.DEFAULT_USER, ActiveMQConnectionFactory.DEFAULT_PASSWORD, "tcp://192.168.0.115:61616" ); //2.通过ConnectionFactory工厂对象我们创建一个Connection连接,并且调用Connection的start方法开启连接, // connection默认是关闭的 Connection connection = connectionFactory.createConnection(); connection.start(); //3.通过Connection工厂对象创建Session会话(上下文环境对象),用于接收消息, // 参数1为是否启用事务,参数2为签收模式,一般我们设置自动签收 Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); //4.通过Session创建Destination对象,指的是一个客户端用来指定生产消息目标和消费信息来源的对象, // 在P2P模式中,Destination被称作Queue即队列;在Pub/Sub模式,Destination被称作Topic即主题。 // 在程序中可以使用多个Queue和Topic Destination destination = session.createQueue("Queue_01"); //5.我们需要通过Session对象创建消息的发送和接收对象(生产者和消费者),MessageProducer/MessageConsumer MessageProducer messageProducer = session.createProducer(destination); //6.我们可以使用MessageProducer的setDeliveryMode()方法为其设置持久化特性和非持久化特性(DeliveryMode) messageProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); //7.使用JMS规范的TextMessage形式创建数据(通过Session对象),并用MessageProducer的send方法发送数据。 // 同理客户端使用receive方法进行接收数据 for (int i = 1; i <= 10; i++) { TextMessage textMessage = session.createTextMessage(); textMessage.setText("Sender: HelloWorld! Message_ID = "+i); messageProducer.send(textMessage); } //8.关闭Connection连接 if (connection != null){ connection.close(); } } } 运行成功后,刷新ActiveMQ管控台,会看到刚刚创建的消息数量和状态点击消息名称查看②消息接收方(消费者): package activemq; import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; public class ActiveMQ_Receiver { public static void main(String[] args) throws JMSException { //1.建立ConnectionFactory工厂对象,需要填入用户名、密码以及要连接的地址,均使用默认即可, // 默认端口为"tcp://localhost:61616" ConnectionFactory connectionFactory = new ActiveMQConnectionFactory( ActiveMQConnectionFactory.DEFAULT_USER, ActiveMQConnectionFactory.DEFAULT_PASSWORD, "tcp://192.168.0.115:61616" ); //2.通过ConnectionFactory工厂对象我们创建一个Connection连接,并且调用Connection的start方法开启连接, // connection默认是关闭的 Connection connection = connectionFactory.createConnection(); connection.start(); //3.通过Connection工厂对象创建Session会话(上下文环境对象),用于接收消息, // 参数1为是否启用事务,参数2为签收模式,一般我们设置自动签收 Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); //4.通过Session创建Destination对象,指的是一个客户端用来指定生产消息目标和消费信息来源的对象, // 在P2P模式中,Destination被称作Queue即队列;在Pub/Sub模式,Destination被称作Topic即主题。 // 在程序中可以使用多个Queue和Topic Destination destination = session.createQueue("Queue_01"); //5.我们需要通过Session对象创建消息的发送和接收对象(生产者和消费者),MessageProducer/MessageConsumer MessageConsumer messageConsumer = session.createConsumer(destination); //6.使用JMS规范的TextMessage形式创建数据(通过Session对象),并用MessageProducer的send方法发送数据。 // 同理客户端使用receive方法进行接收数据 while (true){ TextMessage textMessage = (TextMessage) messageConsumer.receive(); if (textMessage == null) break; System.out.println("Receive_Message: "+textMessage.getText()); } //8.关闭Connection连接 if (connection != null){ connection.close(); } } } 5.ActiveMQ安全机制只有符合认证的用户才能进行发送和接收消息 <plugins> <simpleAuthenticationPlugin> <users> <authenticationUser username="ysx" password="ysx" groups="users,admins"/> </users> </simpleAuthenticationPlugin> </plugins> 在/usr/local/apache-activemq-5.15.8/conf/activemq.xml的大约123行,之前,之后加上上面的插件配置,重启ActiveMQ按之前的程序发送消息就会报错:需要对程序进行修改(生产者和消费者都要改)待续。。。
1.斐波那契数列 package algorithm; public class Algorithm_1 { public static void main(String[] args) { System.out.println(getNum(5)); } /** * 用递归实现斐波那契数列,适用于求解比较小的位置数值 * 0 1 1 2 3 5 8 13 21... * @param n * @return */ public static int getNum(int n){ if(n <= 2){ return 1; }else { return getNum(n-1) + getNum(n-2); } } } 2.求阶乘 package algorithm; public class Algorithm_2 { public static void main(String[] args) { System.out.print(getNum(5)); } /** * 求阶乘 * n!=n*(n-1)*(n-2)*...*1 * @param n * @return */ public static int getNum(int n){ if(n == 1){ System.out.print(n + "="); return 1; }else { System.out.print(n + "*"); return getNum(n-1) * n; } } } 3.列出某个目录下所有子目录和文件 package algorithm; import java.io.File; public class Algorithm_3 { public static void main(String[] args) throws Exception { getDir("F:\\Java\\jdk\\db"); } /** * 列出某个目录下所有子目录和文件 * @param path * @return */ public static void getDir(String path) throws Exception { File file = new File(path); if(file.isDirectory()){ System.out.println("Dir" + file.getPath()); File[] fileArr = file.listFiles(); for (File f : fileArr) { getDir(f.getPath()); } }else if (file.isFile()){ System.out.println("File" + file.getPath()); }else { throw new Exception(file.getPath() + "非Dir非File?!"); } } } 4.汉诺塔问题 package algorithm; public class Algorithm_4 { private final static String from = "柱子A"; private final static String mid = "柱子B"; private final static String to = "柱子C"; public static void main(String[] args) { move(5, from, mid, to); } /** * 汉诺塔 * func: * if n!=0 then ;预定值 * func(n-1, a, c, b) ;将n-1个盘子由a移动到b,以c为辅助柱子(注意参数顺序) * move a[n] to c ;将a上的最后一个盘子移动到c * func(n-1, b, a, c) ;将n-1个盘子由b移动到c,以a为辅助柱子 * endif ;完成 * @param n * @param from2 * @param mid2 * @param to2 */ public static void move(int n, String from2, String mid2, String to2){ if(n == 1){ System.out.println("移动盘子 " + n + " 从 " + from2 + " 到 " + to2); }else { move(n-1, from2, to2, mid2); System.out.println("移动盘子 " + n + " 从 " + from2 + " 到 " + to2); move(n-1, mid2, from2, to2); } } } 5.二分法查找 package algorithm; /** * 二分法查找值 * 一定是有序表,升序降序都可以 * 原理就是找中间值 */ public class Algorithm_5 { public static void main(String[] args) { int[] array = {1,3,5,7,9,12,14,15,19,20,22,23,28,30}; System.out.println(search(array, 0, array.length-1, 20)); } /** * @param array 有序数组,但不限于数组 * @param start 开始查找的数组下标 * @param end 结束查找的数组下标 * @param searchValue 要搜索的值 * @return */ public static int search(int[] array, int start, int end, int searchValue){ if (array != null && array.length > 0){ int middle = (start + end) / 2; int middleValue = array[middle]; if (searchValue == middleValue){ return middle; }else if (searchValue < middleValue){ //查询值小于中值,在中值前面再次搜索,缩小范围 return search(array, start, middle-1, searchValue); }else { //查询值大于中值,在中值后面再次搜索,缩小范围 return search(array, middle+1, end, searchValue); } }else { return -1; } } } 结束
PageHelper-5.1.1和PageHelper-4.0.0是有区别的PageHelper-4.0.0的版本时,Mybatis全局配置文件SqlMapConfig.xml的内容是: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <plugins> <!-- com.github.pagehelper 为 PageHelper 类所在包名 --> <plugin interceptor="com.github.pagehelper.PageHelper"> <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL 六种数据库--> <property name="dialect" value="mysql"/> </plugin> </plugins> </configuration> 当我PageHelper的版本改为5.1.1时,tomcat启动报错:java.lang.ClassCastException: com.github.pagehelper.PageHelper cannot be cast to org.apache.ibatis.plugin.Interceptor这句报错信息说明PageHelper这个类没有实现Interceptor这个接口,我们看下源码: package com.github.pagehelper; import com.github.pagehelper.dialect.AbstractHelperDialect; import com.github.pagehelper.page.PageAutoDialect; import com.github.pagehelper.page.PageMethod; import com.github.pagehelper.page.PageParams; import com.github.pagehelper.util.StringUtil; import java.util.List; import java.util.Properties; import org.apache.ibatis.cache.CacheKey; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.session.RowBounds; public class PageHelper extends PageMethod implements Dialect { private PageParams pageParams; private PageAutoDialect autoDialect; public PageHelper() { } PageHelper可以看到,这个类并没有实现Interceptor这个接口在这里我们要了解下PageHelper在Mybatis中是如何工作的:通过mybatis的pulgin实现了Interceptor接口,从而获得要执行的sql语句实现分页技术,而我们的PageHelper5.1.1版本中的这个类,并没有出现implements Interceptor,找找pagehelper这个包下的其他类PageInterceptor类内容如下: package com.github.pagehelper; @Intercepts({@Signature( type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class} ), @Signature( type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class} )}) public class PageInterceptor implements Interceptor { protected Cache<String, MappedStatement> msCountMap = null; private Dialect dialect; private String default_dialect_class = "com.github.pagehelper.PageHelper"; private Field additionalParametersField; private String countSuffix = "_COUNT"; public PageInterceptor() { } PageInterceptor实现了Interceptor接口将SqlMapConfig.xml做修改: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <plugins> <!-- com.github.pagehelper 为 PageHelper 类所在包名 --> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL 六种数据库--> <property name="dialect" value="mysql"/> </plugin> </plugins> </configuration> 重新运行tomcat然后。。。网上找的:PageHelper插件4.0.0以后的版本支持自动识别使用的数据库,可以不用配置 <property name="dialect" value="mysql"/> 将SqlMapConfig.xml做修改: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <plugins> <!-- com.github.pagehelper 为 PageHelper 类所在包名 --> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL 六种数据库--> <!--<property name="dialect" value="mysql"/>--> </plugin> </plugins> </configuration> 再次重新运行tomcat成功了!结束
1.PSps命令将某个进程显示出来grep命令是查找中间的|是管道命令 是指ps命令与grep同时执行ps是LINUX下最常用的也是非常强大的进程查看命令grep命令是查找,是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。以下这条命令是检查java 进程是否存在:ps -ef |grep java字段含义如下: UID PID PPID C STIME TTY TIME CMD zzw 14124 13991 0 00:38 pts/0 00:00:00 grep --color=auto dae **UID :程序被该 UID 所拥有PID :就是这个程序的 IDPPID :则是其上级父程序的ID,如果父进程先于子进程关闭,子进程将有init进程(PPID=1)管理C :CPU使用的资源百分比STIME :系统启动时间TTY :登入者的终端机位置TIME :使用掉的CPU时间。CMD :所下达的是什么指令**2.SCP不同IP的服务器间传输文件 scp ./nginx.conf root@192.168.0.116:/usr/local/nginx/conf/
安装Tomcat前需要先安装JDK: java -version 如果没有安装,请参考链接:https://yq.aliyun.com/articles/653373?spm=a2c4e.11155435.0.0.c92b3312NrGMmg下载tomcat 8.0.53:https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.0.53/bin/apache-tomcat-8.0.53.tar.gz解压文件apache-tomcat-8.0.53.tar.gz tar -zxvf ./apache-tomcat-8.0.53.tar.gz 解压过的压缩包记得删掉,会占用服务器磁盘空间 rm -rf ./apache-tomcat-8.0.53.tar.gz 进入bin目录 cd /usr/local/apache-tomcat-8.0.53/bin 启动tomcat服务:sh ./startup.sh浏览器访问:http://192.168.43.61:8080/停止tomcat服务:sh ./shutdown.sh结束
2019年08月
/**
* 获取用户实际IP地址
* @param request 当前请求对象
* @return 实际IP地址
*/
public static String getRemoteIp(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
logger.trace("当前IP来源[X-Forwarded-For], 值[{}]", ip);
if(!StringUtils.isEmpty(ip) && !NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)){
//多次反向代理后会有多个ip值,第一个ip才是真实ip
int index = ip.indexOf(',');
if(index != -1){
return ip.substring(0, index);
}else{
return ip;
}
}
ip = request.getHeader("X-Real-IP");
logger.trace("当前IP来源[X-Real-IP], 值[{}]", ip);
if(!StringUtils.isEmpty(ip) && !NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)){
return ip;
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
logger.trace("当前IP来源[Proxy-Client-IP], 值[{}]", ip);
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
logger.trace("当前IP来源[WL-Proxy-Client-IP], 值[{}]", ip);
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
logger.trace("当前IP来源[HTTP_CLIENT_IP], 值[{}]", ip);
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
logger.trace("当前IP来源[HTTP_X_FORWARDED_FOR], 值[{}]", ip);
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
logger.trace("当前IP来源[getRemoteAddr], 值[{}]", ip);
}
if ("0:0:0:0:0:0:0:1".equals(ip)) {
String ipv4FromLocal = getIpv4FromLocal();
if (StringUtils.isNotEmpty(ipv4FromLocal)) {
ip = ipv4FromLocal;
}
}
return ip;
}
/**
* 获取本地IP地址
* @return IP地址
*/
private static String getIpv4FromLocal() {
String ip = null;
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
try {
Process process = Runtime.getRuntime().exec("cmd.exe /c ipconfig | findstr IPv4");
is = process.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String line = br.readLine();
ip = line.substring(line.indexOf(':') + 1).trim();
} catch (IOException e) {
logger.warn("获取本地IP异常", e);
} finally {
try {
if (br != null) {
br.close();
}
if (isr != null) {
isr.close();
}
if (is != null) {
is.close();
}
} catch (IOException e) {
logger.debug("流关闭异常", e);
}
}
return ip;
}
/**
* 获取用户实际IP地址
* @param request 当前请求对象
* @return 实际IP地址
*/
public static String getRemoteIp(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
logger.trace("当前IP来源[X-Forwarded-For], 值[{}]", ip);
if(!StringUtils.isEmpty(ip) && !NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)){
//多次反向代理后会有多个ip值,第一个ip才是真实ip
int index = ip.indexOf(',');
if(index != -1){
return ip.substring(0, index);
}else{
return ip;
}
}
ip = request.getHeader("X-Real-IP");
logger.trace("当前IP来源[X-Real-IP], 值[{}]", ip);
if(!StringUtils.isEmpty(ip) && !NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)){
return ip;
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
logger.trace("当前IP来源[Proxy-Client-IP], 值[{}]", ip);
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
logger.trace("当前IP来源[WL-Proxy-Client-IP], 值[{}]", ip);
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
logger.trace("当前IP来源[HTTP_CLIENT_IP], 值[{}]", ip);
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
logger.trace("当前IP来源[HTTP_X_FORWARDED_FOR], 值[{}]", ip);
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
logger.trace("当前IP来源[getRemoteAddr], 值[{}]", ip);
}
if ("0:0:0:0:0:0:0:1".equals(ip)) {
String ipv4FromLocal = getIpv4FromLocal();
if (StringUtils.isNotEmpty(ipv4FromLocal)) {
ip = ipv4FromLocal;
}
}
return ip;
}
/**
* 获取本地IP地址
* @return IP地址
*/
private static String getIpv4FromLocal() {
String ip = null;
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
try {
Process process = Runtime.getRuntime().exec("cmd.exe /c ipconfig | findstr IPv4");
is = process.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String line = br.readLine();
ip = line.substring(line.indexOf(':') + 1).trim();
} catch (IOException e) {
logger.warn("获取本地IP异常", e);
} finally {
try {
if (br != null) {
br.close();
}
if (isr != null) {
isr.close();
}
if (is != null) {
is.close();
}
} catch (IOException e) {
logger.debug("流关闭异常", e);
}
}
return ip;
}
/**
* 获取用户实际IP地址
* @param request 当前请求对象
* @return 实际IP地址
*/
public static String getRemoteIp(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
logger.trace("当前IP来源[X-Forwarded-For], 值[{}]", ip);
if(!StringUtils.isEmpty(ip) && !NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)){
//多次反向代理后会有多个ip值,第一个ip才是真实ip
int index = ip.indexOf(',');
if(index != -1){
return ip.substring(0, index);
}else{
return ip;
}
}
ip = request.getHeader("X-Real-IP");
logger.trace("当前IP来源[X-Real-IP], 值[{}]", ip);
if(!StringUtils.isEmpty(ip) && !NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)){
return ip;
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
logger.trace("当前IP来源[Proxy-Client-IP], 值[{}]", ip);
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
logger.trace("当前IP来源[WL-Proxy-Client-IP], 值[{}]", ip);
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
logger.trace("当前IP来源[HTTP_CLIENT_IP], 值[{}]", ip);
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
logger.trace("当前IP来源[HTTP_X_FORWARDED_FOR], 值[{}]", ip);
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
logger.trace("当前IP来源[getRemoteAddr], 值[{}]", ip);
}
if ("0:0:0:0:0:0:0:1".equals(ip)) {
String ipv4FromLocal = getIpv4FromLocal();
if (StringUtils.isNotEmpty(ipv4FromLocal)) {
ip = ipv4FromLocal;
}
}
return ip;
}
/**
* 获取本地IP地址
* @return IP地址
*/
private static String getIpv4FromLocal() {
String ip = null;
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
try {
Process process = Runtime.getRuntime().exec("cmd.exe /c ipconfig | findstr IPv4");
is = process.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String line = br.readLine();
ip = line.substring(line.indexOf(':') + 1).trim();
} catch (IOException e) {
logger.warn("获取本地IP异常", e);
} finally {
try {
if (br != null) {
br.close();
}
if (isr != null) {
isr.close();
}
if (is != null) {
is.close();
}
} catch (IOException e) {
logger.debug("流关闭异常", e);
}
}
return ip;
}
/**
* 获取用户实际IP地址
* @param request 当前请求对象
* @return 实际IP地址
*/
public static String getRemoteIp(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
logger.trace("当前IP来源[X-Forwarded-For], 值[{}]", ip);
if(!StringUtils.isEmpty(ip) && !NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)){
//多次反向代理后会有多个ip值,第一个ip才是真实ip
int index = ip.indexOf(',');
if(index != -1){
return ip.substring(0, index);
}else{
return ip;
}
}
ip = request.getHeader("X-Real-IP");
logger.trace("当前IP来源[X-Real-IP], 值[{}]", ip);
if(!StringUtils.isEmpty(ip) && !NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)){
return ip;
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
logger.trace("当前IP来源[Proxy-Client-IP], 值[{}]", ip);
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
logger.trace("当前IP来源[WL-Proxy-Client-IP], 值[{}]", ip);
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
logger.trace("当前IP来源[HTTP_CLIENT_IP], 值[{}]", ip);
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
logger.trace("当前IP来源[HTTP_X_FORWARDED_FOR], 值[{}]", ip);
}
if (StringUtils.isEmpty(ip) || NoticeConstant.UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
logger.trace("当前IP来源[getRemoteAddr], 值[{}]", ip);
}
if ("0:0:0:0:0:0:0:1".equals(ip)) {
String ipv4FromLocal = getIpv4FromLocal();
if (StringUtils.isNotEmpty(ipv4FromLocal)) {
ip = ipv4FromLocal;
}
}
return ip;
}
/**
* 获取本地IP地址
* @return IP地址
*/
private static String getIpv4FromLocal() {
String ip = null;
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
try {
Process process = Runtime.getRuntime().exec("cmd.exe /c ipconfig | findstr IPv4");
is = process.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String line = br.readLine();
ip = line.substring(line.indexOf(':') + 1).trim();
} catch (IOException e) {
logger.warn("获取本地IP异常", e);
} finally {
try {
if (br != null) {
br.close();
}
if (isr != null) {
isr.close();
}
if (is != null) {
is.close();
}
} catch (IOException e) {
logger.debug("流关闭异常", e);
}
}
return ip;
}