【Java】实现对服务器的自动巡检邮件通知

来源:互联网 发布:梁山传奇翅膀升级数据 编辑:程序博客网 时间:2024/05/16 14:59

1、需求

之前一直是手动的巡检,然后贴图,最近服务器数量大增,有点忙不过来了。因为一直用的java,对shell脚本不是特别了解,所以这次用java写了个小项目,实现对多服务器,多任务的巡检,巡检结果有故障的会通过邮件通知。

2、功能和效果

巡检的项目主要是服务,硬盘,内存等,命令可配置,巡检结果以日期和服务器为基准输出文件,错误信息通过邮件通知管理运维人员。



 


3、代码

InspAction.java:

package com.save.action;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import java.util.regex.Matcher;import java.util.regex.Pattern;import org.apache.commons.lang3.StringUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.alibaba.fastjson.JSON;import com.save.pojo.Cmd;import com.save.until.MailUtil;import com.save.until.PropertiesUtil;import com.save.until.SSHCommUtil;import com.save.until.WriteUntil;/** * 巡检任务 * */public class InspAction {    final static Logger logger = LoggerFactory.getLogger(InspAction.class);/*    public static void main(String[] args) {        InspAction n = new InspAction();        try {            n.execute();        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();            logger.error("dd");        }    }*/    /**     * 执行巡检任务     * @param args     */    public void execute() throws Exception{        List<Cmd> list = this.handlerData();        Set<String> mail = new HashSet<String>();        for (Cmd cmd : list) {            String ip = cmd.getIp();            int port = 22;            String localIp = null;            int localPort = 0;            int timeOut = 6000;            String userName = cmd.getUsername();            String password = cmd.getPassword();            String server = cmd.getServer();            String[] cmds = cmd.getCmds();            String[] result = null;            logger.info(ip+"执行巡检任务开始");            try {                result = SSHCommUtil.execShellCmdBySSH(ip, port, localIp, localPort, timeOut,                        userName, password, cmds);            } catch (Exception e) {                e.printStackTrace();                logger.error(ip+"巡检,服务器连接不上");                mail.add(ip+" "+"巡检,服务器连接不上");            }            Date date = new Date();            SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");            String dateString = formatter.format(date);            //1、服务存活验证 2、硬盘占用验证 3、巡检结果写入文件            if (result != null) {                for (String string : result) {                    if (string.contains("ps -ef|grep java")||string.contains("ps -ef|grep mongo")||string.contains("ps -ef|grep redis")) {                        if (!string.contains(server)) {                            mail.add(ip+" "+server+"服务不存在");                        }                    }                    if (string.contains("df -h")) {                        String patt = "^[5]\\d{1}\\%|[5-9]\\d{1}\\%|\\d{3,}\\%$";                        String group = null;                        Pattern p = Pattern.compile(patt);                        Matcher m = p.matcher(string);                        while (m.find()) {                            group = m.group();                        }                        if (!StringUtils.isBlank(group)) {                            mail.add(ip+" "+"硬盘占用超出预警线");                        }                    }                    WriteUntil.createFile("E:\\save", dateString, "\\"+ip+".txt", string);                }                logger.info(ip+"巡检结束");            }        }        //发送故障邮件通知        if (!mail.isEmpty()||mail.size()!=0) {            MailUtil.getInstance().sendMail(mail);        }    }    /**     * 数据处理     * @return     */    private List<Cmd> handlerData(){        logger.info("开始加载需要巡检的服务器数据");        Cmd cmd = null;        List<Cmd> list = new ArrayList<Cmd>();         Map map = PropertiesUtil.getInstance().getAllProperty();        Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();        while (it.hasNext()) {            Map.Entry<String, String> entry = it.next();            cmd =new Cmd();            cmd.setIp(entry.getKey());            Cmd cmd2 = JSON.parseObject(entry.getValue(), Cmd.class);            String[] cmds = cmd2.getShell().split(",");            cmd.setCmds(cmds);            cmd.setServer(cmd2.getServer());            cmd.setUsername(cmd2.getUsername());            cmd.setPassword(cmd2.getPassword());            list.add(cmd);        }        logger.info("数据加载完毕");        return list;    }}


pojo.java:

package com.save.pojo;public class Cmd {    private String ip;    private String username;    private String password;    private String shell;    private String[] cmds;    private String server;    public String getServer() {        return server;    }    public void setServer(String server) {        this.server = server;    }    public String getShell() {        return shell;    }    public void setShell(String shell) {        this.shell = shell;    }    public String getIp() {        return ip;    }    public void setIp(String ip) {        this.ip = ip;    }    public String getUsername() {        return username;    }    public void setUsername(String username) {        this.username = username;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }    public String[] getCmds() {        return cmds;    }    public void setCmds(String[] cmds) {        this.cmds = cmds;    }  }

工具类

JSCHUtil.java:

package com.save.until;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.InetAddress;import java.net.InetSocketAddress;import java.net.Socket;import java.net.UnknownHostException;import java.util.Properties;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.jcraft.jsch.JSch;import com.jcraft.jsch.JSchException;import com.jcraft.jsch.Session;import com.jcraft.jsch.SocketFactory;/** * SSH创建与服务器连接工具类 */public class JSCHUtil {    final static Logger logger = LoggerFactory.getLogger(JSCHUtil.class);  private static JSch jsch = new JSch();  /**   * 创建Session,并打开Session连接   *    */  public static Session createSession(String dstIp, int dstPort,      final String localIp, final int localPort, String userName,      String password, final int timeOut) throws JSchException {    //jsch.setKnownHosts("/home/foo/.ssh/known_hosts");      logger.info("开始连接:"+dstIp);    // 建立一个SSH连接    Session session = jsch.getSession(userName, dstIp, dstPort);    session.setPassword(password);        Properties sshConfig = new Properties();    sshConfig.put("StrictHostKeyChecking", "no");//跳过主机检查    session.setConfig(sshConfig);    // 此socket工厂用于创建目标主机的socket,    // 并创建我们使用的这个socket字节流    session.setSocketFactory(new SocketFactory() {      public OutputStream getOutputStream(Socket socket)          throws IOException {        return socket.getOutputStream();      }      public InputStream getInputStream(Socket socket) throws IOException {        return socket.getInputStream();      }      public Socket createSocket(String host, int port)          throws IOException, UnknownHostException {        Socket socket = new Socket();        if (localIp != null) {          socket.bind(new InetSocketAddress(InetAddress              .getByName(localIp), localPort));        }        socket.connect(            new InetSocketAddress(InetAddress.getByName(host), port),            timeOut);        return socket;      }    });    session.connect(timeOut);    return session;  }}


MailUtil.java:

package com.save.until;import java.util.Properties;import java.util.Set;import javax.mail.Authenticator;import javax.mail.Message;import javax.mail.PasswordAuthentication;import javax.mail.Session;import javax.mail.Transport;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeMessage;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.sun.mail.util.MailSSLSocketFactory;/** * 邮件发送 * */public class MailUtil  {    final static Logger logger = LoggerFactory.getLogger(MailUtil.class);    private static MailUtil instance = new MailUtil();      private MailUtil (){}      public static MailUtil getInstance() {          return instance;      }      public void sendMail(Set<String> mail) {        String from = "XXX@qq.com";// 发件人电子邮箱        String host = "smtp.qq.com"; // 指定发送邮件的主机smtp.qq.com(QQ)|smtp.163.com(网易)        Properties properties =new Properties();        properties.setProperty("mail.smtp.host", host);// 设置邮件服务器        properties.setProperty("mail.smtp.auth", "true");// 打开认证        try {            //QQ邮箱需要下面这段代码,163邮箱不需要            MailSSLSocketFactory sf = new MailSSLSocketFactory();            sf.setTrustAllHosts(true);            properties.put("mail.smtp.ssl.enable", "true");            properties.put("mail.smtp.ssl.socketFactory", sf);            // 1.获取默认session对象            Session session = Session.getDefaultInstance(properties, new Authenticator() {                public PasswordAuthentication getPasswordAuthentication() {                    return new PasswordAuthentication("XXX@qq.com", "XXX"); // 发件人邮箱账号、授权码                }            });            // 2.创建邮件对象            Message message = new MimeMessage(session);            message.setFrom(new InternetAddress(from));            message.addRecipient(Message.RecipientType.TO, new InternetAddress("XXX@qq.com"));            message.setSubject("巡检故障通知");            StringBuffer sb = new StringBuffer();            for (String string : mail) {                sb.append("<div>"+string+"</div><br/><hr/>");            }            String content = sb.toString();            message.setContent(content, "text/html;charset=UTF-8");            Transport.send(message);            logger.info("故障邮件发送成功");        } catch (Exception e) {            e.printStackTrace();        }    }}

PropertiesUtil.java:
package com.save.until; import java.io.File;import java.io.FileOutputStream;   import java.io.InputStream; import java.io.InputStreamReader;import java.io.OutputStream;   import java.net.URI; import java.util.Enumeration;   import java.util.HashMap;   import java.util.Map;   import java.util.Properties;   /** * 读取文件工具类 * */public class PropertiesUtil {            private Properties props;       private URI uri;     private static PropertiesUtil ourInstance = new PropertiesUtil("/config.properties");    public static PropertiesUtil getInstance() {        return ourInstance;    }    public PropertiesUtil(String fileName){           readProperties(fileName);       }       private void readProperties(String fileName) {           try {               props = new Properties();               InputStream fis =getClass().getResourceAsStream(fileName);              InputStreamReader re=new InputStreamReader(fis,"utf-8");            props.load(re);           } catch (Exception e) {               e.printStackTrace();           }       }       /**      * 获取某个属性      */       public String getProperty(String key){           return props.getProperty(key);       }       /**      * 获取所有属性,返回一个map,不常用      * 可以试试props.putAll(t)      */       public Map getAllProperty(){           Map map=new HashMap();           Enumeration enu = props.propertyNames();          while (enu.hasMoreElements()) {               String key = (String) enu.nextElement();               String value = props.getProperty(key);               map.put(key, value);           }           return map;       }       /**      * 在控制台上打印出所有属性,调试时用。      */       public void printProperties(){           props.list(System.out);       }       /**      * 写入properties信息      */       public void writeProperties(String key, String value) {           try {           OutputStream fos = new FileOutputStream(new File(uri));               props.setProperty(key, value);               // 将此 Properties 表中的属性列表(键和元素对)写入输出流               props.store(fos, "『comments』Update key:" + key);           } catch (Exception e) {           e.printStackTrace();         }       }         }


SSHCommUtil.java:

package com.save.until;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.jcraft.jsch.Channel;import com.jcraft.jsch.JSchException;import com.jcraft.jsch.Session;/** * 执行Shell工具类 * */public class SSHCommUtil {    final static Logger logger = LoggerFactory.getLogger(SSHCommUtil.class);    /**     * SHH连接Linux Shell,返回结果      */    public static String[] execShellCmdBySSH(String dstIp, int dstport,            String localIp, int localPort, int timeOut, String userName,            String password, String... cmds) throws Exception {        Session session = null;        Channel channel = null;        InputStream is = null;        OutputStream os = null;        try {            session = JSCHUtil.createSession(dstIp, dstport, localIp,                    localPort, userName, password, timeOut);            logger.info("开始创建channel通道!");            //创建一个channel类型的通道            channel = session.openChannel("shell");            // Enable agent-forwarding.            // ((ChannelShell)channel).setAgentForwarding(true);            // Choose the pty-type "vt102".            // ((ChannelShell)channel).setPtyType("vt102");            // Set environment variable "LANG" as "ja_JP.eucJP".            // ((ChannelShell)channel).setEnv("LANG", "ja_JP.eucJP");            channel.connect();            is = channel.getInputStream();            os = channel.getOutputStream();            String[] result = new String[cmds.length];            for (int i = 0; i < cmds.length; i++) {                result[i] = sendCommand(is, os, cmds[i]);            }            return result;        } catch (JSchException e) {            if (e.getMessage().contains("Auth fail")) {                logger.error(dstIp+"服务器验证失败");                throw new Exception("Auth error");            } else {                logger.error(dstIp+"服务器连接失败");                throw new Exception("Connect error");            }        } catch (Exception e) {            throw e;        } finally {            try {                is.close();            } catch (IOException e) {            }            try {                os.close();            } catch (IOException e) {            }            channel.disconnect();            session.disconnect();        }    }    /**     *执行Shell脚本并返回结果     *      */    private static String sendCommand(InputStream is, OutputStream os,            String cmd) throws IOException {        logger.info("开始执行脚本!");        os.write(cmd.getBytes());        os.flush();        StringBuffer sb = new StringBuffer();        int beat = 0;        while (true) {            if (beat > 3) {                break;            }            if (is.available() > 0) {                byte[] b = new byte[is.available()];                is.read(b);                sb.append(new String(b));                beat = 0;            } else {                if (sb.length() > 0) {                    beat++;                }                try {                    Thread.sleep(sb.toString().trim().length() == 0 ? 1000                            : 300);                } catch (InterruptedException e) {                }            }        }        return sb.toString();    }   }

SSHExcuteCommandHelper.java:

package com.save.until;    import java.io.BufferedReader;    import java.io.IOException;    import java.io.InputStream;    import java.io.InputStreamReader;    import java.util.ArrayList;    import java.util.List;    import com.jcraft.jsch.ChannelExec;    import com.jcraft.jsch.JSch;    import com.jcraft.jsch.JSchException;import com.jcraft.jsch.Session;    /**     * SSH工具类     *      */    public class SSHExcuteCommandHelper {        Session session = null;        ChannelExec openChannel = null;        /**         * @param host  主机ip         * @param name 用户名         * @param pwd 密码         * @param port ssh端口          */        public SSHExcuteCommandHelper(String host, String user, String pwd, int port) {            JSch jsch = new JSch();            try {                session = jsch.getSession(user, host, port);                java.util.Properties config = new java.util.Properties();                config.put("StrictHostKeyChecking", "no");                session.setTimeout(1000);                session.setConfig(config);                session.setPassword(pwd);            } catch (JSchException e) {                e.printStackTrace();            }        }        /**         * 是否连接成功,调用如果不需要调用execCommand方法那么必须调用 disconnect方法关闭session         * @return         */        public boolean canConnection(){            try {                session.connect();                return true;            } catch (JSchException e) {                e.printStackTrace();                return false;            }        }        /**         * 关闭连接         */        public void disconnect(){            if (openChannel != null && !openChannel.isClosed()) {                openChannel.disconnect();            }            if (session != null && session.isConnected()) {                session.disconnect();            }        }        /**         * 执行命令         * @param command         * @return         */        public String execCommand(String command) {            StringBuffer result = new StringBuffer();            try {                if(!session.isConnected()){                    session.connect();                }                openChannel = (ChannelExec) session.openChannel("exec");                openChannel.setCommand(command);                //int exitStatus = openChannel.getExitStatus();                openChannel.connect();                InputStream in = openChannel.getInputStream();                BufferedReader reader = new BufferedReader(                        new InputStreamReader(in));                                String tmpStr = "";                while ((tmpStr = reader.readLine()) != null) {                    result.append(new String(tmpStr.getBytes("gbk"), "UTF-8")).append("\n");                }                            } catch (Exception e) {                e.printStackTrace();                result.append(e.getMessage());            } finally {                disconnect();            }            return result.toString();        }        /**         * 解析         * @param result         * @return         */        public List<List<String>> parseResult(String result){            List<List<String>> parseResult = new ArrayList<List<String>>();            List<String> list = null;            //            for (String line : result.split("\n")) {                list = new ArrayList<String>();                String[] columns = {};                //这个是针对df命令的 [Mounted on] 其实就一个,如果用空格就会分割出两个                if(line.contains("Mounted ")){                    columns = line.replace("Mounted ", "Mounted-").split(" ");                }else{                    columns = line.split(" ");                }                                for (String column : columns) {                    if (!" ".equals(column) && !"".equals(column)) {                        list.add(column);                    }                }                parseResult.add(list);            }            return parseResult;        }          //测试/*        public static void main(String args[]) {            SSHExcuteCommandHelper execute = new SSHExcuteCommandHelper("192.168.175.128", "root", "123456", 22);            System.out.println("是否连接成功"+execute.canConnection());            String s = execute.execCommand("free -m");            System.out.println("解析前");            System.out.println(s);            System.out.println("解析后");            List<List<String>> parseResult = execute.parseResult(s);            for (List<String> l : parseResult) {                System.out.println(l);            }                    }*/    }

WriteUntil.java:

package com.save.until;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.text.SimpleDateFormat;import java.util.Date;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.save.action.InspAction;public class WriteUntil {    final static Logger logger = LoggerFactory.getLogger(WriteUntil.class);    /**     * 新建文件夹,并创建文件写入数据     */    public static void createFile(String basePath,String filePath, String filename, String input) {        String[] dirs = filePath.split("/");        String tempPath = basePath;        for (String dir : dirs) {            if (null == dir || "".equals(dir)) continue;            tempPath += "\\" + dir;        }        //文件夹判断        File dir = new File(tempPath);//"d:\\test_dir"        if (dir.exists()) {            if (dir.isDirectory()) {                logger.info("文件夹存在");            } else {                logger.info("同名文件存在,无法创建目录");            }        } else {            logger.info("文件夹不存在,开始创建");            dir.mkdirs();        }        //文件判断        File file = new File(tempPath+filename);//"d:\\test_file.txt"        if (file.exists()) {            logger.info(filename+"已存在");        } else {            logger.info(filename+"文件不存在,开始创建");            try {                file.createNewFile();            } catch (IOException e) {                e.printStackTrace();            }        }        //写入数据        //方法一、每次写入覆盖之前的       /* try {            FileOutputStream fos = new FileOutputStream(tempPath+filename);            fos.write(input.getBytes());            fos.close();        } catch (Exception e) {            e.printStackTrace();        }*/        try {            FileOutputStream fos = new FileOutputStream(tempPath+filename, true);            fos.write(input.getBytes());            fos.close();        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }      //测试/*    public static void main(String[] args) {        //createFile("E:\\log", "2014/16/2/", "\\2020.txt", "hahha");        Date date = new Date();        SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");        String dateString = formatter.format(date);        System.out.println(dateString);    }*/}

applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">    <!-- 配置作业类 -->    <bean id="InspAction"        class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">        <property name="targetObject">            <bean class="com.save.action.InspAction" />        </property>        <property name="targetMethod" value="execute" />        <property name="concurrent" value="false" /><!-- 作业不并发调度 -->    </bean>    <!-- 配置触发器 -->    <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">        <property name="jobDetail" ref="InspAction" />        <!-- 每天7:00运行一次 -->        <property name="cronExpression" value="0 0 07 * * ?" />    </bean>    <!-- 配置调度工厂 -->    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">        <property name="triggers">            <list>                <ref bean="cronTrigger" />            </list>        </property>    </bean></beans>

config.properties

#测试用服务器192.168.175.128={"username":"root","password":"123456","shell":"ps -ef|grep mongo\n,df -h\n, free -m\n, top\n","server":"mongod"}192.168.175.129={"username":"root","password":"123456","shell":"ps -ef|grep redis\n,df -h\n, free -m\n, top\n","server":"mongod"}

log4j.properties

#指定根Logger,及日志输出级别#大于等于该级别的日志将被输出( DEBUG < INFO < WARN < ERROR < FATAL ),设为OFF可以关闭日志  log4j.rootLogger=INFO, A1,A2  #指定log输出目的,这里设为输出日志到指定目录的文件my.log中  log4j.appender.A1=org.apache.log4j.FileAppender  log4j.appender.A1.File=E:\\save\\log\\xj.log#指定日志信息的格式  log4j.appender.A1.layout=org.apache.log4j.PatternLayoutlog4j.appender.A1.layout.ConversionPattern=%r %d{yyyy-MM-dd HH:mm:ss} %c %p -%m%n   #把A2输出到控制台  log4j.appender.A2=org.apache.log4j.ConsoleAppender  log4j.appender.A2.layout=org.apache.log4j.PatternLayout  log4j.appender.A2.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %c %p -%m%n

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>com.save</groupId>    <artifactId>save-xj</artifactId>    <packaging>war</packaging>    <version>0.0.1-SNAPSHOT</version>    <name>save-xj Maven Webapp</name>    <url>http://maven.apache.org</url>    <dependencies>        <!-- SSH连接 -->        <dependency>            <groupId>com.jcraft</groupId>            <artifactId>jsch</artifactId>            <version>0.1.53</version>        </dependency>        <!-- json转换 -->        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>fastjson</artifactId>            <version>1.2.31</version>        </dependency>        <!-- Spring的包 -->        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-context</artifactId>            <version>3.1.1.RELEASE</version>        </dependency>        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-context-support</artifactId>            <version>3.1.1.RELEASE</version>        </dependency>        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-tx</artifactId>            <version>3.1.1.RELEASE</version>        </dependency>        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-web</artifactId>            <version>3.0.5.RELEASE</version>        </dependency>        <!-- 定时任务 -->        <dependency>            <groupId>org.quartz-scheduler</groupId>            <artifactId>quartz</artifactId>            <version>1.8.5</version>        </dependency>        <!-- 日志的包 -->        <dependency>            <groupId>log4j</groupId>            <artifactId>log4j</artifactId>            <version>1.2.17</version>        </dependency>        <dependency>            <groupId>org.slf4j</groupId>            <artifactId>slf4j-log4j12</artifactId>            <version>1.7.21</version>        </dependency>        <!-- 邮件 -->        <dependency>            <groupId>com.sun.mail</groupId>            <artifactId>javax.mail</artifactId>            <version>1.4.4</version>        </dependency>        <dependency>            <groupId>javax.mail</groupId>            <artifactId>mail</artifactId>            <version>1.4</version>        </dependency>        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->        <dependency>            <groupId>org.apache.commons</groupId>            <artifactId>commons-lang3</artifactId>            <version>3.4</version>        </dependency>    </dependencies>    <build>        <plugins>            <!-- 配置Tomcat插件 -->            <plugin>                <groupId>org.apache.tomcat.maven</groupId>                <artifactId>tomcat7-maven-plugin</artifactId>                <version>2.2</version>                <configuration>                    <port>8080</port>                    <path>/</path>                </configuration>            </plugin>        </plugins>    </build></project>



0 0
原创粉丝点击