当前位置: 移动技术网 > IT编程>开发语言>Java > java实现对服务器的自动巡检邮件通知

java实现对服务器的自动巡检邮件通知

2019年07月22日  | 移动技术网IT编程  | 我要评论

1、需求

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

2、功能和效果

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

3、代码

action:

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;
/**
 * 巡检任务
 * @author zhangzhuo
 *
 */
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:

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;
 } 
}

工具类:

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创建与服务器连接工具类
 * @author 张卓
 * 2017-4-21
 */
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;
 }
}

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;
/**
 * 邮件发送
 * @author zhangzhuo
 *
 */
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();
  }
 }

}

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; 
/**
 * 读取文件工具类
 * @author zhangzhuo
 *
 */
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(); 
  } 
 }  
 
}
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工具类
 * @author zhangzhuo
 *
 */
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();
 }
 
}

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);
   }
   
  }*/
 }

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;
/**
 * 
 * @author zhangzhuo
 *
 */
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.patternlayout
log4j.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>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网