之前用的柳大神寫的Servlet+jdbc寫的微信服務号,别的項目全是Stringmvc,就把項目更改了,做個記錄
項目是maven管理,需要的包配置在pom檔案,在最底下,以後寫避免找不到
一些基礎類就不貼了,很多網站都有
Controller類:
<pre name="code" class="java"><span style="font-size:14px;">import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping(value="core")
public class CoreServiceController {
private Logger log = Logger.getLogger(CoreServiceController.class);
/**
* 校驗資訊是否是從微信伺服器發過來的。
*
* @param weChat
* @param out
*/
@RequestMapping(method = { RequestMethod.GET })
public void doget(HttpServletRequest request, HttpServletResponse response, PrintWriter out) {
// 微信加密簽名
String signature = request.getParameter("signature");
// 時間戳
String timestamp = request.getParameter("timestamp");
// 随機數
String nonce = request.getParameter("nonce");
// 随機字元串
String echostr = request.getParameter("echostr");
// 通過檢驗signature對請求進行校驗,若校驗成功則原樣傳回echostr,表示接入成功,否則接入失敗
if (SignUtil.checkSignature(signature, timestamp, nonce)) {
out.print(echostr);
} else {
System.out.println("不是微信伺服器發來的請求!");
}
out.flush();
out.close();
}
/**
* 微信消息的處理
* @param request
*/
@RequestMapping(method = { RequestMethod.POST })
public void dopose(HttpServletRequest request, HttpServletResponse response)throws Exception {
/* 消息的接收、處理、響應 */
// 将請求、響應的編碼均設定為UTF-8(防止中文亂碼)
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
// 調用核心業務類接收消息、處理消息
String respMessage = CoreService.processRequest(request,response);
log.info(respMessage);
// 響應消息
PrintWriter out = response.getWriter();
out.print(respMessage);
out.close();
}
}</span>
CoreService類:
public class CoreService {
private static Logger log = LoggerFactory.getLogger(CoreService.class);
private static String emoji(int codePoint){
return String.valueOf(Character.toChars(codePoint));
}
/**
* 處理微信發來的請求
*
* @param request
* @return
*/
public static String processRequest(HttpServletRequest request,HttpServletResponse response) {
// 預設傳回的文本消息内容
String respMessage = null;
try {
String respContent = null;
Map<String, String> requestMap = MessageUtil.parseXml(request);
String fromUserName = requestMap.get("FromUserName");
String toUserName = requestMap.get("ToUserName");
String msgType = requestMap.get("MsgType");
TextMessage textMessage = new TextMessage();
textMessage.setToUserName(fromUserName);
textMessage.setFromUserName(toUserName);
textMessage.setCreateTime(new Date().getTime());
textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
textMessage.setFuncFlag(0);
//文字資訊
if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {
respContent = emoji(0x274C)+"emoji(0x274C)"+"請點選菜單進行操作";
textMessage.setContent(respContent);
respMessage = MessageUtil.textMessageToXml(textMessage);
} // 圖檔消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) {
respContent = emoji(0x274C)+"emoji(0x274C)"+"請點選菜單進行操作";
textMessage.setContent(respContent);respMessage = MessageUtil.textMessageToXml(textMessage); }
// 地理位置消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) {
} // 連結消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) {
respContent = "請點選菜單進行操作"; textMessage.setContent(respContent);
respMessage = MessageUtil.textMessageToXml(textMessage); }
// 音頻消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) {
respContent = "請點選菜單進行操作"; textMessage.setContent(respContent);
respMessage = MessageUtil.textMessageToXml(textMessage); }
// 事件推送 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {
// 事件類型 String eventType = requestMap.get("Event");
// 訂閱 if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {
respContent = emoji(0x1F334)+"謝謝您關注";
textMessage.setContent(respContent);
respMessage = MessageUtil.textMessageToXml(textMessage);}
// 自定義菜單點選事件 else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {
String eventKey = requestMap.get("EventKey");
if (eventKey.equals("11")) {
} else if (eventKey.equals("12")) {
}
}
} catch (Exception e) {
e.printStackTrace();
}
return respMessage;}
</pre><p></p><pre>
BaseMessage類
/**
* 消息基類(公衆帳号 -> 普通使用者)
*
*/
public class BaseMessage {
// 接收方帳号(收到的OpenID)
private String ToUserName;
// 開發者微信号
private String FromUserName;
// 消息建立時間 (整型)
private long CreateTime;
// 消息類型(text/music/news)
private String MsgType;
// 位0x0001被标志時,星标剛收到的消息
private int FuncFlag;
public String getToUserName() {
return ToUserName;
}
public void setToUserName(String toUserName) {
ToUserName = toUserName;
}
public String getFromUserName() {
return FromUserName;
}
public void setFromUserName(String fromUserName) {
FromUserName = fromUserName;
}
public long getCreateTime() {
return CreateTime;
}
public void setCreateTime(long createTime) {
CreateTime = createTime;
}
public String getMsgType() {
return MsgType;
}
public void setMsgType(String msgType) {
MsgType = msgType;
}
public int getFuncFlag() {
return FuncFlag;
}
public void setFuncFlag(int funcFlag) {
FuncFlag = funcFlag;
}
}
TextMessage
package com.ysh.message.resp;
/**
* 文本消息
*
*/
public class TextMessage extends BaseMessage {
// 回複的消息内容
private String Content;
public String getContent() {
return Content;
}
public void setContent(String content) {
Content = content;
}
}
MessageUtil
import java.io.InputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.dom4j.io.SAXReader;
import org.dom4j.Document;
import org.dom4j.Element;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;
/**
* 消息工具類
*
*/
public class MessageUtil {
/**
* 傳回消息類型:文本
*/
public static final String RESP_MESSAGE_TYPE_TEXT = "text";
/**
* 傳回消息類型:音樂
*/
public static final String RESP_MESSAGE_TYPE_MUSIC = "music";
/**
* 傳回消息類型:圖文
*/
public static final String RESP_MESSAGE_TYPE_NEWS = "news";
/**
* 請求消息類型:文本
*/
public static final String REQ_MESSAGE_TYPE_TEXT = "text";
/**
* 請求消息類型:圖檔
*/
public static final String REQ_MESSAGE_TYPE_IMAGE = "image";
/**
* 請求消息類型:連結
*/
public static final String REQ_MESSAGE_TYPE_LINK = "link";
/**
* 請求消息類型:地理位置
*/
public static final String REQ_MESSAGE_TYPE_LOCATION = "location";
/**
* 請求消息類型:音頻
*/
public static final String REQ_MESSAGE_TYPE_VOICE = "voice";
/**
* 請求消息類型:推送
*/
public static final String REQ_MESSAGE_TYPE_EVENT = "event";
/**
* 事件類型:subscribe(訂閱)
*/
public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";
/**
* 事件類型:unsubscribe(取消訂閱)
*/
public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";
/**
* 事件類型:CLICK(自定義菜單點選事件)
*/
public static final String EVENT_TYPE_CLICK = "CLICK";
/**
* 解析微信發來的請求(XML)
*
* @param request
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public static Map<String, String> parseXml(HttpServletRequest request)
throws Exception {
// 将解析結果存儲在HashMap中
Map<String, String> map = new HashMap<String, String>();
// 從request中取得輸入流
InputStream inputStream = request.getInputStream();
// 讀取輸入流
SAXReader reader = new SAXReader();
Document document = reader.read(inputStream);
// 得到xml根元素
Element root = document.getRootElement();
// 得到根元素的所有子節點
List<Element> elementList = root.elements();
// 周遊所有子節點
for (Element e : elementList)
map.put(e.getName(), e.getText());
// 釋放資源
inputStream.close();
inputStream = null;
return map;
}
/**
* 文本消息對象轉換成xml
*
* @param textMessage
* 文本消息對象
* @return xml
*/
public static String textMessageToXml(com.ysh.message.resp.TextMessage textMessage) {
xstream.alias("xml", textMessage.getClass());
return xstream.toXML(textMessage);
}
/**
* 音樂消息對象轉換成xml
*
* @param musicMessage 音樂消息對象
* @return xml
*/
public static String messageToXml(MusicMessage musicMessage) {
xstream.alias("xml", musicMessage.getClass());
return xstream.toXML(musicMessage);
}
/**
* 圖文消息對象轉換成xml
*
* @param newsMessage
* 圖文消息對象
* @return xml
*/
public static String newsMessageToXml(NewsMessage newsMessage) {
xstream.alias("xml", newsMessage.getClass());
xstream.alias("item", new Article().getClass());
return xstream.toXML(newsMessage);
}
/**
* 擴充xstream,使其支援CDATA塊
*
* @date 2013-05-19
*/
private static XStream xstream = new XStream(new XppDriver() {
public HierarchicalStreamWriter createWriter(Writer out) {
return new PrettyPrintWriter(out) {
// 對所有xml節點的轉換都增加CDATA标記
boolean cdata = true;
@SuppressWarnings("unchecked")
public void startNode(String name, Class clazz) {
super.startNode(name, clazz);
}
protected void writeText(QuickWriter writer, String text) {
if (cdata) {
writer.write("<![CDATA[");
writer.write(text);
writer.write("]]>");
} else {
writer.write(text);
}
}
};
}
});
/**
* 主菜單
*
* @return
*/
// public static String getMainMenu() {
// StringBuffer buffer = new StringBuffer();
// buffer.append("您好,雲生活機器人為您服務,請回複數字選擇服務:").append("\n\n");
// buffer.append("1 曆史上的今天").append("\n");
// buffer.append("2 經典遊戲").append("\n");
// buffer.append("3 周邊搜尋(待開發)").append("\n");
// buffer.append("4 天氣查詢(待開發)").append("\n");
// buffer.append("6 美女電台(待開發)").append("\n");
// buffer.append("7 公交查詢(待開發)").append("\n");
// buffer.append("8 聊天唠嗑(待開發)").append("\n\n");
// buffer.append("回複“?”顯示此幫助菜單");
// return buffer.toString();
// }
//
// public static String youxi() {
// StringBuffer buffer = new StringBuffer();
// buffer.append("可以直接點選玩").append("\n\n");
// buffer.append("1 <a href=\"http://www.duopao.com/games/info?game_code=g20140120233048400063\">雷電</a>經典").append("\n");
// buffer.append("2 <a href=\"http://www.duopao.com/games/info?game_code=g20140212153040377809\">Flappy Bird</a>就是小鳥").append("\n");
// buffer.append("3 <a href=\"http://www.duopao.com/games/info?game_code=g20140324115109221580\">2048</a>數字遊戲").append("\n");
// return buffer.toString();
// }
/**
* 文本消息對象轉換成xml
*
* @param textMessage 文本消息對象
* @return xml
*/
public static String messageToXml(TextMessage textMessage) {
xstream.alias("xml", textMessage.getClass());
return xstream.toXML(textMessage);
}
/**
* 圖文消息對象轉換成xml
*
* @param newsMessage 圖文消息對象
* @return xml
*/
public static String messageToXml(NewsMessage newsMessage) {
xstream.alias("xml", newsMessage.getClass());
xstream.alias("item", new Article().getClass());
return xstream.toXML(newsMessage);
}
NewsMessage
public class NewsMessage extends BaseMessage {
// 圖文消息個數,限制為10條以内
private int ArticleCount;
// 多條圖文消息資訊,預設第一個item為大圖
private List<Article> Articles;
public int getArticleCount() {
return ArticleCount;
}
public void setArticleCount(int articleCount) {
ArticleCount = articleCount;
}
public List<Article> getArticles() {
return Articles;
}
public void setArticles(List<Article> articles) {
Articles = articles;
}
}
下面是配置檔案
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:hello-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<bean
class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="username">
<value>***</value>
</property>
<property name="password">
<value><span style="font-family: Arial, Helvetica, sans-serif;">***</span><span style="font-family: Arial, Helvetica, sans-serif;"></value></span>
</property>
<property name="url">
<value>jdbc:mysql://localhost:8080/test?zeroDateTimeBehavior=round&tinyInt1isBit=false
</value>
</property>
</bean>
<!-- 事物 -->
<bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" /></bean>
<!-- dao -->
<bean id="testDao" class="dao.testDaoimpl">
<!-- service -->
<bean id="coreService" class="service.CoreService"></beans>
hello.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<context:component-scan base-package="com.ysh.controller" />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/jsp/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
</beans:beans>
pom
<dependency>
<groupId>xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.2.2</version>
</dependency>
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jcifs</groupId>
<artifactId>jcifs</artifactId>
<version>0.7.0b5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-servlet_2.5_spec</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.5</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-spring</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-http</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-local</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>2.4.0</version>
</dependency>
<!-- json -->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.3</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>integration</artifactId>
<version>1.7.10</version>
</dependency>
<dependency>
<groupId>org.apache.directory.studio</groupId>
<artifactId>org.dom4j.dom4j</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>