* 1、实现翻译功能;
接受“翻译XX”的输入,返回翻译结果;
目录结构
- 项目结构图
- 增加和修改相关源代码
- 结果对类
- 翻译结果类
- 百度翻译服务类
-
核心Service
- Maven工程文件
- 上传本地代码到GitHub
- 上传工程WAR档至SAE
- 微信客户端测试
- 参考文档
- 完整项目源代码
项目结构图
源代码文件说明
序号 | 文件名 | 说明 | 操作 |
1 | ResultPair.java | 结果对类 | 新增 |
2 | TranslateResult.java | 翻译结果类 | 新增 |
3 | BaiduTranslateService | 百度翻译服务类 | 新增 |
4 | CoreService.java | 核心服务类,新增处理各种输入,返回不同图文信息 | 更新 |
5 | pom.xml | 新增解析gson的jar | 更新 |
增加和修改相关源代码
结果对类
ResultPair.java
package com.coderdream.model;
/**
* 结果对
*/
public class ResultPair {
/**
* 原文
*/
private String src;
/**
* 译文
*/
private String dst;
public String getSrc() {
return src;
}
public void setSrc(String src) {
this.src = src;
}
public String getDst() {
return dst;
}
public void setDst(String dst) {
this.dst = dst;
}
}
翻译结果类
TranslateResult.java
package com.coderdream.model;
import java.util.List;
/**
* 调用百度翻译API查询结果
*/
public class TranslateResult {
/**
* 实际采用的源语言
*/
private String from;
/**
* 实际采用的目标语言
*/
private String to;
/**
* 结果体
*/
private List<ResultPair> trans_result;
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public List<ResultPair> getTrans_result() {
return trans_result;
}
public void setTrans_result(List<ResultPair> trans_result) {
this.trans_result = trans_result;
}
}
百度翻译服务类
BaiduTranslateService.java
package com.coderdream.service;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import com.coderdream.model.TranslateResult;
import com.google.gson.Gson;
/**
*
*/
public class BaiduTranslateService {
/**
* 发起http请求获取返回结果
*
* @param requestUrl
* 请求地址
* @return
*/
public static String httpRequest(String requestUrl) {
StringBuffer buffer = new StringBuffer();
try {
URL url = new URL(requestUrl);
HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();
httpUrlConn.setDoOutput(false);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
httpUrlConn.setRequestMethod("GET");
httpUrlConn.connect();
// 将返回的输入流转换成字符串
InputStream inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
// 释放资源
inputStream.close();
inputStream = null;
httpUrlConn.disconnect();
} catch (Exception e) {
}
return buffer.toString();
}
/**
* utf编码
*
* @param source
* @return
*/
public static String urlEncodeUTF8(String source) {
String result = source;
try {
result = java.net.URLEncoder.encode(source, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
/**
* 翻译(中->英 英->中 日->中 )
*
* @param source
* @return
*/
public static String translate(String source) {
String dst = null;
// 组装查询地址
String requestUrl = "http://openapi.baidu.com/public/2.0/bmt/translate?client_id=j8pX3RW2MWgP9qLKKrGt25Cc&q={keyWord}&from=auto&to=auto";
// 对参数q的值进行urlEncode utf-8编码
requestUrl = requestUrl.replace("{keyWord}", urlEncodeUTF8(source));
// 查询并解析结果
try {
// 查询并获取返回结果
String json = httpRequest(requestUrl);
// 通过Gson工具将json转换成TranslateResult对象
TranslateResult translateResult = new Gson().fromJson(json, TranslateResult.class);
// 取出translateResult中的译文
dst = translateResult.getTrans_result().get(0).getDst();
} catch (Exception e) {
e.printStackTrace();
}
if (null == dst) {
dst = "翻译系统异常,请稍候尝试!";
}
return dst;
}
public static void main(String[] args) {
// System.setProperty("http.proxySet", "true");
// System.setProperty("http.proxyHost", "proxy.jpn.hp.com");
// System.setProperty("http.proxyPort", "8080");
// 翻译结果:The network really powerful
// System.out.println(translate("网络真强大"));
System.out.println(translate("明天"));
}
}
核心服务类
更新代码后,能实现翻译功能;接受“翻译XX”的输入,返回翻译结果;
CoreService.java
package com.coderdream.service;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import com.coderdream.bean.Logging;
import com.coderdream.dao.LoggingDao;
import com.coderdream.model.Article;
import com.coderdream.model.NewsMessage;
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");
SimpleDateFormat f_timestamp = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
Logging logging = new Logging(f_timestamp.format(Calendar.getInstance().getTime()), "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(f_timestamp.format(Calendar.getInstance().getTime()), "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(f_timestamp.format(Calendar.getInstance().getTime()), "DEBUG", TAG, logStr);
loggingDao.addLogging(logging);
// 文本消息
if (msgType.equals(MessageUtil.MESSAGE_TYPE_TEXT)) {
respContent = "您发送的是文本消息!";
// 接收用户发送的文本消息内容
String content = requestMap.get("Content").trim();
// 创建图文消息
NewsMessage newsMessage = new NewsMessage();
newsMessage.setToUserName(fromUserName);
newsMessage.setFromUserName(toUserName);
newsMessage.setCreateTime(new Date().getTime());
newsMessage.setMsgType(MessageUtil.MESSAGE_TYPE_NEWS);
// newsMessage.setFuncFlag(0);
List<Article> articleList = new ArrayList<Article>();
if (content.startsWith("翻译")) {
String keyWord = content.replaceAll("^翻译", "").trim();
if ("".equals(keyWord)) {
textMessage.setContent(getTranslateUsage());
} else {
textMessage.setContent(BaiduTranslateService.translate(keyWord));
}
respContent = textMessage.getContent();
// 设置文本消息的内容
textMessage.setContent(respContent);
// 将文本消息对象转换成xml
respXml = MessageUtil.messageToXml(textMessage);
}
// 如果以“历史”2个字开头
else if (content.startsWith("历史")) {
// 将歌曲2个字及歌曲后面的+、空格、-等特殊符号去掉
String dayStr = content.substring(2);
// 如果只输入历史两个字,在输出当天的历史
if (null == dayStr || "".equals(dayStr.trim())) {
DateFormat df = new SimpleDateFormat("MMdd");
dayStr = df.format(Calendar.getInstance().getTime());
}
respContent = TodayInHistoryService.getTodayInHistoryInfoFromDB(dayStr);
textMessage.setContent(respContent);
// 将图文消息对象转换成xml字符串
return MessageUtil.messageToXml(textMessage);
}
// 单图文消息
else if ("1".equals(content)) {
Article article = new Article();
article.setTitle("微信公众帐号开发教程Java版");
article.setDescription("柳峰,80后,微信公众帐号开发经验4个月。为帮助初学者入门,特推出此系列教程,也希望借此机会认识更多同行!");
article.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
article.setUrl("http://blog.csdn.net/lyq8479?toUserName=" + fromUserName + "&toUserName="
+ toUserName);
articleList.add(article);
// 设置图文消息个数
newsMessage.setArticleCount(articleList.size());
// 设置图文消息包含的图文集合
newsMessage.setArticles(articleList);
// 将图文消息对象转换成xml字符串
return MessageUtil.messageToXml(newsMessage);
}
// 单图文消息---不含图片
else if ("2".equals(content)) {
Article article = new Article();
article.setTitle("微信公众帐号开发教程Java版");
// 图文消息中可以使用QQ表情、符号表情
article.setDescription("柳峰,80后,"
// + emoji(0x1F6B9)
+ ",微信公众帐号开发经验4个月。为帮助初学者入门,特推出此系列连载教程,也希望借此机会认识更多同行!\n\n目前已推出教程共12篇,包括接口配置、消息封装、框架搭建、QQ表情发送、符号表情发送等。\n\n后期还计划推出一些实用功能的开发讲解,例如:天气预报、周边搜索、聊天功能等。");
// 将图片置为空
article.setPicUrl("");
article.setUrl("http://blog.csdn.net/lyq8479?toUserName=" + fromUserName + "&toUserName="
+ toUserName);
articleList.add(article);
newsMessage.setArticleCount(articleList.size());
newsMessage.setArticles(articleList);
return MessageUtil.messageToXml(newsMessage);
}
// 多图文消息
else if ("3".equals(content)) {
Article article1 = new Article();
article1.setTitle("微信公众帐号开发教程\n引言");
article1.setDescription("");
article1.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
article1.setUrl("http://blog.csdn.net/lyq8479/article/details/8937622?toUserName=" + fromUserName
+ "&toUserName=" + toUserName);
Article article2 = new Article();
article2.setTitle("第2篇\n微信公众帐号的类型");
article2.setDescription("");
article2.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
article2.setUrl("http://blog.csdn.net/lyq8479/article/details/8941577?toUserName=" + fromUserName
+ "&toUserName=" + toUserName);
Article article3 = new Article();
article3.setTitle("关注页面");
article3.setDescription("关注页面");
article3.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
article3.setUrl("http://wxquan.sinaapp.com/follow.jsp?toUserName=" + fromUserName + "&toUserName="
+ toUserName);
articleList.add(article1);
articleList.add(article2);
articleList.add(article3);
newsMessage.setArticleCount(articleList.size());
newsMessage.setArticles(articleList);
return MessageUtil.messageToXml(newsMessage);
}
// 多图文消息---首条消息不含图片
else if ("4".equals(content)) {
Article article1 = new Article();
article1.setTitle("微信公众帐号开发教程Java版");
article1.setDescription("");
// 将图片置为空
article1.setPicUrl("");
article1.setUrl("http://blog.csdn.net/lyq8479");
Article article2 = new Article();
article2.setTitle("第4篇\n消息及消息处理工具的封装");
article2.setDescription("");
article2.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
article2.setUrl("http://blog.csdn.net/lyq8479/article/details/8949088?toUserName=" + fromUserName
+ "&toUserName=" + toUserName);
Article article3 = new Article();
article3.setTitle("第5篇\n各种消息的接收与响应");
article3.setDescription("");
article3.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
article3.setUrl("http://blog.csdn.net/lyq8479/article/details/8952173?toUserName=" + fromUserName
+ "&toUserName=" + toUserName);
Article article4 = new Article();
article4.setTitle("第6篇\n文本消息的内容长度限制揭秘");
article4.setDescription("");
article4.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
article4.setUrl("http://blog.csdn.net/lyq8479/article/details/8967824?toUserName=" + fromUserName
+ "&toUserName=" + toUserName);
articleList.add(article1);
articleList.add(article2);
articleList.add(article3);
articleList.add(article4);
newsMessage.setArticleCount(articleList.size());
newsMessage.setArticles(articleList);
return MessageUtil.messageToXml(newsMessage);
}
// 多图文消息---最后一条消息不含图片
else if ("5".equals(content)) {
Article article1 = new Article();
article1.setTitle("第7篇\n文本消息中换行符的使用");
article1.setDescription("");
article1.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
article1.setUrl("http://blog.csdn.net/lyq8479/article/details/9141467?toUserName=" + fromUserName
+ "&toUserName=" + toUserName);
Article article2 = new Article();
article2.setTitle("第8篇\n文本消息中使用网页超链接");
article2.setDescription("");
article2.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
article2.setUrl("http://blog.csdn.net/lyq8479/article/details/9157455?toUserName=" + fromUserName
+ "&toUserName=" + toUserName);
Article article3 = new Article();
article3.setTitle("如果觉得文章对你有所帮助,请通过博客留言或关注微信公众帐号xiaoqrobot来支持柳峰!");
article3.setDescription("");
// 将图片置为空
article3.setPicUrl("");
article3.setUrl("http://blog.csdn.net/lyq8479");
articleList.add(article1);
articleList.add(article2);
articleList.add(article3);
newsMessage.setArticleCount(articleList.size());
newsMessage.setArticles(articleList);
// respContent = messageUtil.messageToXml(newsMessage);
return MessageUtil.messageToXml(newsMessage);
}
}
// 图片消息
else if (msgType.equals(MessageUtil.MESSAGE_TYPE_IMAGE)) {
respContent = "您发送的是图片消息!";
}
// 语音消息
else if (msgType.equals(MessageUtil.MESSAGE_TYPE_VOICE)) {
respContent = "您发送的是语音消息!";
}
// 视频消息
else if (msgType.equals(MessageUtil.MESSAGE_TYPE_VIDEO)) {
respContent = "您发送的是视频消息!";
}
// 地理位置消息
else if (msgType.equals(MessageUtil.MESSAGE_TYPE_LOCATION)) {
respContent = "您发送的是地理位置消息!";
}
// 链接消息
else if (msgType.equals(MessageUtil.MESSAGE_TYPE_LINK)) {
respContent = "您发送的是链接消息!";
}
// 事件推送
else if (msgType.equals(MessageUtil.MESSAGE_TYPE_EVENT)) {
// 事件类型
String eventType = requestMap.get("Event");
// 关注
if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {
respContent = "谢谢您的关注!";
}
// 取消关注
else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) {
// TODO 取消订阅后用户不会再收到公众账号发送的消息,因此不需要回复
}
// 扫描带参数二维码
else if (eventType.equals(MessageUtil.EVENT_TYPE_SCAN)) {
// TODO 处理扫描带参数二维码事件
}
// 上报地理位置
else if (eventType.equals(MessageUtil.EVENT_TYPE_LOCATION)) {
// TODO 处理上报地理位置事件
}
// 自定义菜单
else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {
// TODO 处理菜单点击事件
}
}
logStr = "#4# respContent: " + respContent;
logger.debug(TAG + logStr);
logging = new Logging(f_timestamp.format(Calendar.getInstance().getTime()), "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(f_timestamp.format(Calendar.getInstance().getTime()), "DEBUG", TAG, logStr);
loggingDao.addLogging(logging);
} catch (Exception e) {
e.printStackTrace();
}
return respXml;
}
/**
* 翻译使用指南
*
* @return
*/
public static String getTranslateUsage() {
StringBuffer buffer = new StringBuffer();
// buffer.append(XiaoqUtil.emoji(0xe148)).append("Q译通使用指南").append("\n\n");
buffer.append("Q译通为用户提供专业的多语言翻译服务,目前支持以下翻译方向:").append("\n");
buffer.append(" 中 -> 英").append("\n");
buffer.append(" 英 -> 中").append("\n");
buffer.append(" 日 -> 中").append("\n\n");
buffer.append("使用示例:").append("\n");
buffer.append(" 翻译我是中国人").append("\n");
buffer.append(" 翻译dream").append("\n");
buffer.append(" 翻译さようなら").append("\n\n");
buffer.append("回复“?”显示主菜单");
return buffer.toString();
}
}
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> <gson.version>2.2.4</gson.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> <!-- 测试的时候用到,打包的后WAR里没有 --> <dependency> <groupId>org.dbunit</groupId> <artifactId>dbunit</artifactId> <version>${dbunit.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>${gson.version}</version> </dependency> </dependencies> <build> <finalName>wxquan</finalName> </build> </project>
上传本地代码到GitHub
将新增和修改过的代码上传到GitHub
上传工程WAR档至SAE
将eclipse中的工程导出为wxquan.war档,上传到SAE中,更新已有的版本。
微信客户端测试
登录微信网页版:https://wx.qq.com/
输入“翻译你好”和“翻译程序员”,返回相应的英文。
参考文档
完整源代码