微信公众平台开发实战(03) 运行日志写入SAE数据库

目录结构

  • 项目结构图
  • 增加相关源代码
    1. 日志实体类
    2. 日志访问类
    3. 日志访问测试类
    4. 测试工具类
    5. 数据库工具类
    6. 核心Service

    7. Maven工程文件
  • 上传本地代码到GitHub
  • 上传工程WAR档至SAE
  • 微信客户端测试
  • 查看SAE数据库
  • 参考文档
  • 完整项目源代码

项目结构图

微信公众平台开发实战(03) 运行日志写入SAE数据库
 

源代码文件说明

序号文件名说明操作
1readme.md说明文档更新
2log4j.properties日志属性文件未更新
3BaseMessage.java消息基类未更新
4TextMessage.java文本消息类未更新
5SignUtil.java取Token服务类未更新
6MessageUtil.java消息处理工具类未更新
7CoreServlet.java核心Servlet,增加doPost()方法未更新
8CoreService.java核心服务类,处理前台传过来的请求,并返回响应更新
9web.xmlWeb项目配置文件(这里主要配置Servlet的信息)未更新
10index.jsp首页文件,显示时间信息,主要用来判断工程是否部署成功未更新
11Logging.java日志实体类新增
12LoggingDao.java日志操作类新增
13LoggingDaoTest.java日志测试类新增
14EntitiesHelper.java测试辅助类新增
15jdbc.properties数据库配置文件新增
16DBUtil.java数据库工具类新增
17logging.xml测试数据文件新增
18logging_add.xml测试数据文件新增

增加相关源代码

日志实体类

Logging.java

package com.coderdream.bean;

public class Logging {

	// `id` int(11) NOT NULL AUTO_INCREMENT,
	private int id;
	// `log_date` datetime DEFAULT NULL,
	// private Timestamp logDate; 由于MySQL不能存入带毫米数的Timestamp,这里直接存字符串
	private String logDate;
	// `log_level` varchar(64) DEFAULT NULL,
	private String logLevel;
	// `location` varchar(256) DEFAULT NULL,
	private String location;
	// `message` varchar(1024) DEFAULT NULL,
	private String message;

	public Logging() {

	}

	public Logging(int id, String logDate, String logLevel, String location, String message) {
		this.id = id;
		this.logDate = logDate;
		this.logLevel = logLevel;
		this.location = location;
		this.message = message;
	}

	public Logging(String logDate, String logLevel, String location, String message) {
		this.logDate = logDate;
		this.logLevel = logLevel;
		this.location = location;
		this.message = message;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getLogDate() {
		return logDate;
	}

	public void setLogDate(String logDate) {
		this.logDate = logDate;
	}

	public String getLogLevel() {
		return logLevel;
	}

	public void setLogLevel(String logLevel) {
		this.logLevel = logLevel;
	}

	public String getLocation() {
		return location;
	}

	public void setLocation(String location) {
		this.location = location;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	@Override
	public String toString() {
		return "Logging [id=" + id + ", logDate=" + logDate + ", logLevel=" + logLevel + ", location=" + location
						+ ", message=" + message + "]";
	}

}

日志操作类 

LoggingDao.java

package com.coderdream.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;

import com.coderdream.bean.Logging;
import com.coderdream.util.DBUtil;

public class LoggingDao {

	private String location;

	public static String TAG = "LoggingDao";

	private Logger logger = Logger.getLogger(LoggingDao.class);

	public LoggingDao() {
	}

	public LoggingDao(String location) {
		this.location = location;
	}

	public int addLogging(Logging logging) {
		logger.debug(TAG + "###0###");

		String sql = "INSERT INTO logging (log_date, log_level, location, message) VALUES (?,?,?,?)";

		int count = 0;
		Connection con = null;
		PreparedStatement ps = null;
		try {
			con = DBUtil.getConnection();
			logger.debug(TAG + con);
			ps = con.prepareStatement(sql);
			ps.setString(1, logging.getLogDate());
			ps.setString(2, logging.getLogLevel());
			ps.setString(3, logging.getLocation());
			ps.setString(4, logging.getMessage());
			count = ps.executeUpdate();
			logger.debug(TAG + "count: " + count);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBUtil.close(ps);
			DBUtil.close(con);
		}
		return count;
	}

	public int debug(String message) {
		if (!logger.isDebugEnabled()) {
			return 0;
		}

		logger.debug(TAG + "###0###");
		String sql = "INSERT INTO logging (log_date, log_level, location, message) VALUES (?,?,?,?)";

		int count = 0;
		Connection con = null;
		PreparedStatement pre = null;
		try {
			con = DBUtil.getConnection();
			logger.debug(TAG + " ###2### Connection: " + con);
			pre = con.prepareStatement(sql);
			logger.debug(TAG + " ###3### PreparedStatement: " + pre);
			Date date = Calendar.getInstance().getTime();
			SimpleDateFormat f_timestamp = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
			String logTimestampStr = f_timestamp.format(date);
			pre.setString(1, logTimestampStr);
			pre.setString(2, "DEBUG");
			pre.setString(3, location);
			pre.setString(4, message);
			count = pre.executeUpdate();
			logger.debug(TAG + "###4### count: " + count);
		} catch (Exception e) {
			logger.debug(TAG + "###5### Exception: " + e.getMessage());
			e.printStackTrace();
		} finally {
			DBUtil.close(pre);
			DBUtil.close(con);
		}
		return count;
	}

	public static int debug(String location, String message) {
		if (!Logger.getLogger(LoggingDao.class).isDebugEnabled()) {
			return 0;
		}
		String sql = "INSERT INTO logging (log_date, log_level, location, message) VALUES (?,?,?,?)";

		int count = 0;
		Connection con = null;
		PreparedStatement pre = null;
		try {
			con = DBUtil.getConnection();
			pre = con.prepareStatement(sql);
			Date date = Calendar.getInstance().getTime();
			SimpleDateFormat f_timestamp = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
			String logTimestampStr = f_timestamp.format(date);
			pre.setString(1, logTimestampStr);
			pre.setString(2, "DEBUG");
			pre.setString(3, location);
			pre.setString(4, message);
			count = pre.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBUtil.close(pre);
			DBUtil.close(con);
		}
		return count;
	}

	public int error(String message) {
		logger.debug(TAG + "###0###");
		String sql = "INSERT INTO logging (log_date, log_level, location, message) VALUES (?,?,?,?)";

		int count = 0;
		Connection con = null;
		PreparedStatement pre = null;
		try {
			con = DBUtil.getConnection();
			logger.debug(TAG + con);
			pre = con.prepareStatement(sql);
			Date date = Calendar.getInstance().getTime();
			SimpleDateFormat f_timestamp = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
			String logTimestampStr = f_timestamp.format(date);
			pre.setString(1, logTimestampStr);
			pre.setString(2, "ERROR");
			pre.setString(3, location);
			pre.setString(4, message);
			count = pre.executeUpdate();
			logger.debug(TAG + "count: " + count);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBUtil.close(pre);
			DBUtil.close(con);
		}
		return count;
	}

	public static int error(String location, String message) {
		String sql = "INSERT INTO logging (log_date, log_level, location, message) VALUES (?,?,?,?)";

		int count = 0;
		Connection con = null;
		PreparedStatement pre = null;
		try {
			con = DBUtil.getConnection();
			pre = con.prepareStatement(sql);
			Date date = Calendar.getInstance().getTime();
			SimpleDateFormat f_timestamp = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
			String logTimestampStr = f_timestamp.format(date);
			pre.setString(1, logTimestampStr);
			pre.setString(2, "ERROR");
			pre.setString(3, location);
			pre.setString(4, message);
			count = pre.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBUtil.close(pre);
			DBUtil.close(con);
		}
		return count;
	}

	PreparedStatement pre;
	ResultSet rs;

	/**
	 * @author help
	 * 
	 *         显示所有记录
	 * @return
	 */
	public List<Logging> findLoggings() {

		String sql = "select * from logging order by id";
		List<Logging> list = new ArrayList<Logging>();

		// 获取prepareStatement对象
		Connection con = null;
		try {
			con = DBUtil.getConnection();
			pre = con.prepareStatement(sql);
			rs = pre.executeQuery();

			while (rs.next()) {
				Logging logging = new Logging();
				logging.setId(rs.getInt("id"));
				logging.setLogDate(rs.getString("log_date"));
				logging.setLogLevel(rs.getString("log_level"));
				logging.setLocation(rs.getString("location"));
				logging.setMessage(rs.getString("message"));
				list.add(logging);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBUtil.close(pre);
			DBUtil.close(con);
		}
		return list;
	}

	/**
	 * @author help
	 * 
	 *         显示所有记录
	 * @return
	 */
	public Logging findLogging(int id) {

		String sql = "select * from logging where id=?";
		List<Logging> list = new ArrayList<Logging>();

		// 获取prepareStatement对象
		Connection con = null;
		try {
			con = DBUtil.getConnection();
			pre = con.prepareStatement(sql);
			pre.setInt(1, id);
			rs = pre.executeQuery();

			while (rs.next()) {
				Logging logging = new Logging();
				logging.setId(rs.getInt("id"));
				logging.setLogDate(rs.getString("log_date"));
				logging.setLogLevel(rs.getString("log_level"));
				logging.setLocation(rs.getString("location"));
				logging.setMessage(rs.getString("message"));
				list.add(logging);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBUtil.close(pre);
			DBUtil.close(con);
		}

		if (null != list && 0 < list.size()) {
			return list.get(0);
		}

		return null;
	}

	public String getLocation() {
		return location;
	}

	public void setLocation(String location) {
		this.location = location;
	}

}

日志操作测试类

LoggingDaoTest.java

package com.coderdream.dao;

import java.io.FileInputStream;
import java.io.FileWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.dbunit.Assertion;
import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.database.QueryDataSet;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.ITable;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.dataset.xml.FlatXmlProducer;
import org.dbunit.operation.DatabaseOperation;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.InputSource;

import com.coderdream.bean.Logging;
import com.coderdream.util.DBUtil;
import com.coderdream.util.EntitiesHelper;

/**
 * <pre>
 * DBUnit使用步骤
 *  1)下载地址为http://sourceforge.net/projects/dbunit/files/ 
 *  2)导入DBUnit所需两个jar文件(dbunit.jar和slf4j-api.jar)
 *  3)创建DBUnit用到的xml格式的测试数据,xml文件名建议与表名相同 
 *  4)创建DBUnit的Connection和DataSet,然后开始进行各项测试工作
 * 
 * 使用注解@BeforeClass,在globalInit()执行打开数据库操作;
 * 使用注解@AfterClass,在globalDestroy()执行数据库关闭操作;
 * 
 * 使用注解@Before,每次测试执行之前都先执行init()操作;
 * 使用注解@After,每次测试执行之后都会执行destroy()操作;
 * 
 * DBUtil提供数据库操作方法。
 * </pre>
 * 
 * @author CoderDream
 * @date 2014年10月15日
 * 
 */
public class LoggingDaoTest {

	public static String TAG = "LoggingDaoTest";
	private static final Logger logger = LoggerFactory.getLogger(LoggingDaoTest.class);
	private static Connection conn;
	private static IDatabaseConnection dbUnitConn;
	private static String DATA_BACKUP_FILE = "dataBackup_logging.xml";

	private static String LOGGING_DATA_FILE = "logging.xml";

	@BeforeClass
	public static void globalInit() {
		conn = DBUtil.getConnection();
		System.out.println("DB-Unit Get Connection: " + conn);
		try {
			// DBUnit中用来操作数据文件的Connection需依赖于数据库连接的Connection
			dbUnitConn = new DatabaseConnection(conn);
		} catch (DatabaseUnitException e) {
			e.printStackTrace();
		}
	}

	@AfterClass
	public static void globalDestroy() {
		DBUtil.close(conn);
		if (null != dbUnitConn) {
			try {
				dbUnitConn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 备份数据库中某一张或某几张表的数据,同时将xml文件中的数据插入到数据库中
	 */
	@Before
	public void init() throws Exception {
		logger.debug("Before #### init");
		// 通过QueryDataSet可以有效的选择要处理的表来作为DataSet
		QueryDataSet dataSet = new QueryDataSet(dbUnitConn);
		// 这里指定只备份t_logging表中的数据,如果想备份多个表,那就再addTable(tableName)即可
		dataSet.addTable("logging");
		FlatXmlDataSet.write(dataSet, new FileWriter(DATA_BACKUP_FILE));
	}

	/**
	 * 还原表数据
	 */
	@After
	public void destroy() throws Exception {
		IDataSet dataSet = new FlatXmlDataSet(new FlatXmlProducer(
						new InputSource(new FileInputStream(DATA_BACKUP_FILE))));
		DatabaseOperation.CLEAN_INSERT.execute(dbUnitConn, dataSet);
	}

	/**
	 * <pre>
	 * 测试查询方法
	 * 		 DatabaseOperation类的几个常量值
	 * 		 CLEAN_INSERT----先删除数据库中的所有数据,然后将xml中的数据插入数据库
	 * 		 DELETE----------如果数据库存在与xml记录的相同的数据,则删除数据库中的该条数据
	 * 		 DELETE_ALL------删除数据库中的所有数据
	 * 		 INSERT----------将xml中的数据插入数据库
	 * 		 NONE------------nothing to do
	 * 		 REFRESH---------刷新数据库中的数据
	 * 		 TRUNCATE_TABLE--清空表中的数据
	 * 		 UPDATE----------将数据库中的那条数据更新为xml中的数据
	 * </pre>
	 */
	@Test
	public void testFindLogging() throws Exception {

		IDataSet dataSet = new FlatXmlDataSet(new FlatXmlProducer(new InputSource(LoggingDaoTest.class.getClassLoader()
						.getResourceAsStream(LOGGING_DATA_FILE))));
		DatabaseOperation.TRUNCATE_TABLE.execute(dbUnitConn, dataSet);
		DatabaseOperation.CLEAN_INSERT.execute(dbUnitConn, dataSet);
		
		// 下面开始数据测试
		LoggingDao loggingDao = new LoggingDao();
		Logging logging = loggingDao.findLogging(1);
		
		// 预想结果和实际结果的比较
		EntitiesHelper.assertLogging(logging);
	}

	/**
	 * 更新,添加,删除等方法,可以利用Assertion.assertEquals() 方法,拿表的整体来比较。
	 */
	@Test
	public void testAddLogging() throws Exception {
		IDataSet dataSet = new FlatXmlDataSet(new FlatXmlProducer(new InputSource(LoggingDaoTest.class.getClassLoader()
						.getResourceAsStream(LOGGING_DATA_FILE))));
		DatabaseOperation.TRUNCATE_TABLE.execute(dbUnitConn, dataSet);
		DatabaseOperation.CLEAN_INSERT.execute(dbUnitConn, dataSet);

		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		String time = df.format(new Date(1413993830024l));
		// Timestamp ts = Timestamp.valueOf(time);
		String logStr = "FirstLogging";
		// 被追加的记录
		Logging newLogging = new Logging(time, "DEBUG", TAG, logStr);

		// 执行追加 addLogging 方法
		LoggingDao loggingDao = new LoggingDao();
		int result = loggingDao.addLogging(newLogging);
		Assert.assertEquals(1, result);

		// 预期结果取得
		IDataSet expectedDataSet = new FlatXmlDataSet(new FlatXmlProducer(new InputSource(LoggingDaoTest.class
						.getClassLoader().getResourceAsStream("logging_add.xml"))));
		ITable expectedTable = expectedDataSet.getTable("logging");

		// 实际结果取得(取此时数据库中的数据)
		// Creates a dataset corresponding to the entire database
		IDataSet databaseDataSet = dbUnitConn.createDataSet();
		ITable actualTable = databaseDataSet.getTable("logging");

		// 预想结果和实际结果的比较
		Assertion.assertEquals(expectedTable, actualTable);
	}
}

测试辅助类

EntitiestHelper.java

package com.coderdream.util;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.junit.Assert;

import com.coderdream.bean.Logging;

public class EntitiesHelper {

	public static void assertLogging(Logging expected, Logging actual) {
		Assert.assertNotNull(expected);
		Assert.assertEquals(expected.getId(), actual.getId());
		Assert.assertEquals(expected.getLogDate(), actual.getLogDate());
		Assert.assertEquals(expected.getLogLevel(), actual.getLogLevel());
		Assert.assertEquals(expected.getLocation(), actual.getLocation());
		Assert.assertEquals(expected.getMessage(), actual.getMessage());
	}

	public static void assertLogging(Logging expected) {
		String logStr = "InitLogging";
		// Timestamp sDate = new Timestamp(1413993830024l);
		// 2014-10-23 00:03:50.024
		// time: 1413993830024
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		String time = df.format(new Date(1413993830024l));
		Logging baseLogging = new Logging(1, time, "DEBUG", "LoggingDaoTest", logStr);
		assertLogging(expected, baseLogging);
	}
}

数据库工具类

DBUtil.java

package com.coderdream.util;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;

public class DBUtil {

	public static Connection getConnection() {
		Connection con = null;
		Properties prop = new Properties();// 属性集合对象
		InputStream fis;
		try {
			fis = DBUtil.class.getClassLoader().getResourceAsStream(
					"jdbc.properties");
			prop.load(fis);// 将属性文件流装载到Properties对象中

			String driver = prop.getProperty("driver");

			String username = prop.getProperty("username");
			String password = prop.getProperty("password");
			String url = prop.getProperty("url");// 使用从库的域名

			Map<String, String> envMap = System.getenv();

			String os = envMap.get("OS");
			// local
			if (null != os && "Windows_NT".equals(os.trim())) {
				username = prop.getProperty("local.username");
				password = prop.getProperty("local.password");
				url = prop.getProperty("local.url");
			}
			// SAE
			else {
				username = prop.getProperty("sae.username");
				password = prop.getProperty("sae.password");
				url = prop.getProperty("sae.url");
			}

			Class.forName(driver).newInstance();
			con = DriverManager.getConnection(url, username, password);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return con;
	}

	public static void close(Connection con) {
		try {
			if (null != con) {
				con.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void close(PreparedStatement ps) {
		try {
			if (null != ps) {
				ps.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void close(ResultSet rs) {
		try {
			if (null != rs) {
				rs.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

}

核心服务类

CoreService.java

package com.coderdream.service;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

import org.apache.log4j.Logger;

import com.coderdream.bean.Logging;
import com.coderdream.dao.LoggingDao;
import com.coderdream.model.TextMessage;
import com.coderdream.util.MessageUtil;

/**
 * 核心服务类
 */
public class CoreService {

	public static String TAG = "CoreService";

	private Logger logger = Logger.getLogger(CoreService.class);

	/**
	 * 处理微信发来的请求
	 * 
	 * @param request
	 * @return xml
	 */
	public String processRequest(InputStream inputStream) {
		logger.debug(TAG + " #1# processRequest");
		//Timestamp sDate = new Timestamp(Calendar.getInstance().getTime().getTime());
		Date date = Calendar.getInstance().getTime();
		SimpleDateFormat f_timestamp = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
		String logTimestampStr = f_timestamp.format(date);
		Logging logging = new Logging(logTimestampStr, "DEBUG", TAG, "#1# processRequest");
		LoggingDao loggingDao = new LoggingDao();
		loggingDao.addLogging(logging);
		// xml格式的消息数据
		String respXml = null;
		// 默认返回的文本消息内容
		String respContent = "未知的消息类型!";
		try {
			// 调用parseXml方法解析请求消息
			Map<String, String> requestMap = MessageUtil.parseXml(inputStream);
			// 发送方帐号
			String fromUserName = requestMap.get("FromUserName");
			// 开发者微信号
			String toUserName = requestMap.get("ToUserName");
			// 消息类型
			String msgType = requestMap.get("MsgType");
			String logStr = "#2# fromUserName: " + fromUserName + ", toUserName: " + toUserName + ", msgType: "
							+ msgType;
			logger.debug(TAG + logStr);
			logging = new Logging(logTimestampStr, "DEBUG", TAG, logStr);
			loggingDao.addLogging(logging);

			// 回复文本消息
			TextMessage textMessage = new TextMessage();
			textMessage.setToUserName(fromUserName);
			textMessage.setFromUserName(toUserName);
			textMessage.setCreateTime(new Date().getTime());
			textMessage.setMsgType(MessageUtil.MESSAGE_TYPE_TEXT);
			logStr = "#3# textMessage: " + textMessage.toString();
			logger.debug(TAG + logStr);
			logging = new Logging(logTimestampStr, "DEBUG", TAG, logStr);
			loggingDao.addLogging(logging);

			// 文本消息
			if (msgType.equals(MessageUtil.MESSAGE_TYPE_TEXT)) {
				respContent = "您发送的是文本消息!";
			}
			logStr = "#4# respContent: " + respContent;
			logger.debug(TAG + logStr);
			logging = new Logging(logTimestampStr, "DEBUG", TAG, logStr);
			loggingDao.addLogging(logging);

			// 设置文本消息的内容
			textMessage.setContent(respContent);
			// 将文本消息对象转换成xml
			respXml = MessageUtil.messageToXml(textMessage);
			logStr = "#5# respXml: " + respXml;
			logger.debug(TAG + logStr);
			logging = new Logging(logTimestampStr, "DEBUG", TAG, logStr);
			loggingDao.addLogging(logging);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return respXml;
	}
}

Maven工程文件

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.coderdream</groupId>
	<artifactId>wxquan</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>wxquan Maven Webapp</name>
	<url>http://maven.apache.org</url>

	<properties>
		<junit.version>4.11</junit.version>
		<servlet.api.version>2.5</servlet.api.version>
		<jsp.api.version>2.1</jsp.api.version>
		<slf4j.version>1.7.5</slf4j.version>
		<dom4j.version>1.6.1</dom4j.version>
		<xstream.version>1.4.7</xstream.version>
		<mysql.version>5.1.17</mysql.version>
		<dbunit.version>2.4.9</dbunit.version>
	</properties>

	<dependencies>
		<!-- 测试的时候用到,打包的时候没有 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>

		<!-- 编译的时候用到,打包的时候没有 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>${servlet.api.version}</version>
			<scope>provided</scope>
		</dependency>

		<!-- 编译的时候用到,打包的时候没有 -->
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>${jsp.api.version}</version>
			<scope>provided</scope>
		</dependency>

		<!-- 日志包 -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${slf4j.version}</version>
		</dependency>

		<!-- 打包的时候剔除 xml-apis-1.0.b2.jar SAE中不支持 -->
		<dependency>
			<groupId>dom4j</groupId>
			<artifactId>dom4j</artifactId>
			<version>${dom4j.version}</version>
			<exclusions>
				<exclusion>
					<groupId>xml-apis</groupId>
					<artifactId>xml-apis</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

		<!-- 打包的时候剔除 xml-apis-1.0.b2.jar SAE中不支持 -->
		<!-- 这个jar必须用1.4.7的高版本,否则SAE不支持 -->
		<!-- 详细原因:http://blog.csdn.net/lyq8479/article/details/38878543 -->
		<dependency>
			<groupId>com.thoughtworks.xstream</groupId>
			<artifactId>xstream</artifactId>
			<version>${xstream.version}</version>
		</dependency>

		<!-- 编译的时候用到,打包的时候没有,SAE已包含此jar -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql.version}</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>org.dbunit</groupId>
			<artifactId>dbunit</artifactId>
			<version>${dbunit.version}</version>
			<scope>test</scope>
		</dependency>

	</dependencies>
	<build>
		<finalName>wxquan</finalName>
	</build>
</project>

上传本地代码到GitHub

将新增和修改过的代码上传到GitHub

微信公众平台开发实战(03) 运行日志写入SAE数据库
 
 

上传工程WAR档至SAE

将eclipse中的工程导出为wxquan.war档,上传到SAE中,更新已有的版本。

微信客户端测试

 登录微信网页版:https://wx.qq.com/

 输入“测试”,返回“您发送的是文本消息”。

查看SAE数据库

查询SAE数据库,发现logging表中已写入相关数据:
微信公众平台开发实战(03) 运行日志写入SAE数据库
 
 

参考文档

  1.  

完整源代码

相关推荐