Я был занят интерфейсом некоторое время. Я прочитал документы с нуля и наступил на множество ошибок. Я прошел через это недавно. Я подумал о том, чтобы сделать некоторое краткое изложение, чтобы я мог просмотреть его в будущем, когда я его разрабатываю. Я также дам ссылку на студентов, которые работают над соответствующими проектами.
На самом деле, после этого, вы обнаружите, что это не сложно. Общая идея заключается в том, что пользовательские сообщения и разжигания событий, требуемые разработчиками, будут инициировать запрос через сервер WeChat и перенаправить его на адрес URL -адреса сервера, который вы настраивали на общедоступной платформе. Сервер WeChat принесет четыре параметра: Signature, TimeStamp, Nonce и EchoStr. Наш сервер будет разыскивать токен, настроенный на общедоступной платформе и загруженной TimeStamp. Nonce будет зашифрован в SHA1 и соответствует подписи. Верните туру, чтобы указать, что доступ успешен.
1. Общедоступная конфигурация платформы
2. Контроллер
@Controller@requestMapping ("/weChat") publicClass weChatController {@Value ("$ {dnbx_token}") частная строка dnbx_token; private static final logger = loggerfactory.getlogger (wechatcontroller.class); @return * @throhs ioexception */ @requestmapping (value = "/connect", method = {requestmethod.get, requestmethod.post}) @responsebodypublicvoid connectwiexin (httpservletrequest, httpservletresponse response) throws wears {// set the sept secoding aeprest-response) request.setcharacterencoding ("UTF-8"); // Сервер WeChat использует кодирование UTF-8 при сообщении почты, и при получении необходимо использовать то же кодирование, в противном случае китайский искаженный код будет искаженным кодом; response.setcharacterencoding ("UTF-8"); // При ответе на сообщения (отвечая на пользователя) метод кодирования также установлен на UTF-8, принцип такой же, как и выше; boolean isget = request.getMethod (). tolowercase (). equals ("get"); Printwriter out = response.getWriter (); try {if (iSet) {строка signature = request.getParameter ("signature"); // weChat шифровать подпись строки timestamp = request.getParameter ("timestamp"); // timestamp nonce = request.getParameter ("nonce"); request.getParameter ("echoStr"); // Случайная строка // Проверьте запрос, проверив подпись. Если проверка успешна, верните EchoStr, как есть, указывая на то, что доступ успешен. В противном случае, доступ не работает, если (signutil.checksignature (dnbx_token, signature, timestamp, nonce)) {logger.info («Подключение сервера Weixin успешно.»); response.getWriter (). написать (echoStr); } else {logger.error ("Не удалось проверить подпись!"); }} else {string respmessage = "Сообщение об исключении!"; try {respmessage = wechatservice.weixinpost (request); out.write (respmessage); logger.info («Запрос успешно завершен»); logger.info («на сервер weixin»+respmessage); Вейсин! »); }}} catch (Exception e) {logger.error ("Подключить сервер weixin is error.");} наконец {out.close ();}}}3. Проверка подписи.
Из контроллера выше мы видим, что я инкапсуляю сигнал класса инструментов, называемый контрольной сигнализацией и прошел в четыре значения, DNBX_TOKEN, Signature, TimeStamp, Nonce. Этот процесс очень важен. На самом деле, мы можем понять это как процесс шифрования и дешифрования значения, передаваемого WeChat. Чтобы обеспечить безопасность, все интерфейсы во многих крупных проектах будут иметь такой процесс проверки. DNBX_TOKEN Мы настроили токеновую строку на общедоступной платформе WeChat, сохраняйте идею конфиденциальной! Остальные три - это параметры, отправленные сервером WeChat для отправки запроса GET. Мы выполняем слой шифрования SHA1:
открытый класс Signutil { / *** Подписание проверки* @param token token weChat token Server, настроенный в файле env.properties и настроенный в центре разработчиков должен быть согласованной* @param signature. Сервер WeChat отправляет SHA1 Scrypted Sertiactiate* @param timestamp Timestam подпись, строка временной метки, строка nonce) {string [] arr = new String [] {token, timestamp, nonce}; // Сортировка словаря порядок токена, временной метки и нонсе; // сплачивать три строки параметров в строку для строки шифрования SHA1 TMPSTR = SHA1.ENCODE (ARR [0] + ARR [1] + ARR [2]); // Строка зашифрованного SHA1 можно сравнить с подписью, определяя, что запрос поступает от weChat return tmpstr! = NULL? tmpstr.equals (signature.touppercase ()): false; }}SHA1:
/** * WeChat Public Platform (Java) SDK * * SHA1 Algorithm * @author helijun 2016/06/15 19: 49 */public final Class Sha1 {Private Static Final char [] hex_digits = {'0', '1', '2', ',' 4 ', 5', '6', '7', ',', ',', ',', ',', ',', ',', ',', ',' 7 'B', 'c', 'd', 'e', 'f'}; /*** берет сырые байты из дайки и форматирует их правильно. * * @param байт необработанных байтов из дайджеста. * @return Отформатированные байты. */ private static String getFormattedText (byte [] bytes) {int len = bytes.length; StringBuilder buf = new StringBuilder (Len * 2); // преобразовать шифровый текст в шестнадцатеричную строковую форму для (int j = 0; j <len; j ++) {buf.append (hex_digits [(bytes [j] >> 4) & 0x0f]); buf.append (hex_digits [bytes [j] & 0x0f]); } return buf.toString (); } public Static String Encode (String Str) {if (str == null) {return null; } try {MessageDigest messageDigest = messagedigest.getInstance ("sha1"); MessageDigest.Update (str.getBytes ()); return getFormattedText (messagegest.digest ()); } catch (Exception e) {бросить новое runtimeexception (e); }}} Когда вы отправляете и сохраняете его на общедоступной платформе и видите зеленую подсказку «успех доступа», поздравляю с завершением доступа WeChat. Этот процесс требует немного большей осторожности и обратите внимание на случай в алгоритме шифрования. Если доступ не является успешным, большинство случаев являются проблемами с алгоритмом шифрования, проверьте его больше.
4. Реализация службы автоматического ответа сообщения
/*** Запросы процесса от weChat** @param request* @return*/public String weixinpost (httpservletrequest request) {string respmessage = null; try {// xml -запрос map <string, string> requestMap = messageTil.xmltomap (request) ;// sender chound (open_id) string = messageTil = requestMap.get ("fromUsername"); // Строка публичной учетной записи tousername = requestmap.get ("tousername"); // Строка типа сообщения msgtype = requestmap.get ("msgtype"); // Содержимое сообщества строка = requestmap.get ("content"); logger.info ("fromusername is: fromUsermemer storamemer erousermer eresermer erasermer erasermer eraseramer electrenmer electrenmer electrymer electrymer electrymer exect.get (" content "); ", Msgtype IS:" + msgtype); // Текстовое сообщение if (msgtype.equals (messageutil.req_message_type_text)) {// Соответствующая логика выполняется в соответствии с ключевыми словами. Есть только один, который вы не можете себе представить. Нет такой вещи, как вы не можете сделать, если (content.equals ("xxx")) {} // Автоматический ответ TextMessage Text = new TextMessage (); Text.SetContent («Текст" + content); Text.SetTousername (OffUsername); text.setfromusername (tousername); text.setcreatememememememe (new Date (). "); text.setMsgtype (msgtype); respmessage = messageutil.textmessagetoxml (text);}/*else if (msgtype.equals (messageutil.req_message_type_event)) {// event push String eventtype = requestmap.get (" событие "); (EventType.equals (messageUtil.event_type_subscribe)) {// подписаться на respcontent = "Добро пожаловать, чтобы следить за официальной учетной записью XXX!"; return messageresponse.gettextmessag String eventKey = requestMap.get ("evenceKey"); // Значение ключа события, соответствующее значению ключа, указанного при создании пользовательского меню logger.info ("EventKey IS:" +eventKey); return xxx;}} // Включите тест распознавания звука WeChat 2015-30ELS requestMap.get ("распознавание"); // respcontent = "Полученный результат анализа речи:"+recvmessage; if (recvmessage! = null) {respcontent = tulingApipRocess.getTulingResult (recvMessage);} else {respcontent = "То, что вы сказали, слишком распределите, вы можете сказать это еще раз? } // Функция фотографии else if (msgtype.equals ("pic_sysphoto")) {} else {return messageresponse.getTextMessage (fromUsername, tousername, "return yate"); }*// uevent push else if (msgtype.equals (messageutil.req_message_type_event)) {string eventtype = requestmap.get ("event"); // type // specpribe if (eventtype.equals (messageTil.event_type_subscribe)) {textmess = equals = new TextMessage (); Text.SetContent ("Wallow To Bealy, xxx"); Text.SetTouserName (fromUserName); Text.SetFromUsername (tousername); Text.SetCreateTime (new Date (). GetTime () + ""); MessageUtil.textmessageToxml (text);} // todo После отмены подписки, пользователь не может получить сообщение, отправленное официальной учетной записью, поэтому нет необходимости отвечать на сообщение Else if (EventType.equals (messageUtil.event_type_unsubscribe)) {// unsubcribe} // Custom Menu Event If Event If Event If If If If If If If If If Event If If If If If If If If Event If If If If If If Event If If If If Event If I. (EventType.equals (messageUtil.event_type_click)) {string eventkey = requestmap.get ("eventkey"); // Значение ключа события, соответствующее значению ключа, указанному при создании пользовательского меню if (eventkey.equals ("customer_telephone")) {textmessage text = new. TextMessage (); Text.SetContent ("0755-86671980"); Text.SetTouserName (fromUserName); Text.SetFromuserName (touserName); Text.SetCreateTime (new Date (). GetTime () + ""); setmSgtype (messageUtil.resp_messAge_tyste_texte_teceSte_teceSte_teceSte_temesse MessageUtil.textmessageToxml (text);}}}}} catch (Exception e) {logger.error ("error ...")} return respmessage;}Код опубликован, как указано выше. У большинства из них есть комментарии. Если вы читаете основную семантику один раз, вам не нужно их объяснять.
Краткая идея: когда пользователь отправляет сообщение в официальную учетную запись, сервер WeChat запросит пользовательское сообщение через сообщение в соответствующий интерфейс сервера, который мы настроили в формате XML. Что мы должны сделать, так это выполнить соответствующую логическую обработку на основе типа сообщения и т. Д., И вернуть окончательный результат возврата на сервер WeChat через формат XML, а затем передать его пользователю.
Есть одно место, которое требует особого внимания:
Красный цвет от имени и tousername - именно противоположность, что также является одной из ловушек. Я помню, что я долгое время отрегулировал его, но это не было проблемой, но это не работало. Наконец, я получил сообщение после изменения этих двух! На самом деле, правильно думать об этом. Когда вы вернетесь на сервер WeChat, ваша роль изменится, поэтому отправитель и приемник определенно противоположны.
5.messageutil
Открытый класс MessageUtil {/ *** Возвращение сообщения типа: текст*/ public Static String 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"; / *** Тип сообщения запроса: Image*/ 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"; / *** Тип сообщения запроса: Audio*/ public static final String req_message_type_voice = "ocole"; / ** * Тип сообщения запроса: push */ public static final String req_message_type_event = "event"; / ** * Тип события: подписка (подписаться) */ public static final String event_type_subscribe = "Подписаться"; / ** * Тип события: UNSOUBSCRIBE (USOUBSCRIBE) */ Public Static Final String Event_type_unsubscribe = "UnsubScribe"; / ** * Тип события: нажмите (Custom Menu Click Event) */ public Static Final String Event_type_click = "click"; }Здесь, чтобы улучшить читаемость и масштабируемость программы, я сделал некоторую инкапсуляцию, определил несколько констант и инкапсулировал некоторые параметры, передаваемые из WeChat в постоянные объекты Java. Основной код, как и выше. Сосредоточьтесь на преобразовании между XML и MAP
На самом деле, эта проблема связана с WeChat с использованием связи XML, и мы обычно используем JSON, поэтому мы можем чувствовать себя немного неудобно за короткий период времени.
1. Пакет банки
<!-Parse XML-> <Dependency> <groupId> dom4j </GroupId> <artifactid> dom4j </artifactid> <sersive> 1.6.1 </version> </depertive> <dehydency> <groupid> com.thoughtworks.xstream </Ground> <strifactid> xstream </artifactid> <serse> 1.4.9 </.9.9 </.4.9 </.4.9 </.9.9 </.4.9 </.4.9 </.4.9 </.1.9 </Ground> <//ArtifactId> </.4.9 </Ground> <//ArtifactId> <//4.
2.xml для карты объекта сбора
/*** xml преобразование в карту* @param request* @return* @throws ioexception*/ @spistresswarnings ("unchecked") public static map <string, string> xmltomap (httpservletrequest). null; try {ins = request.getInputStream ();} catch (ioException e1) {e1.printstacktrace ();} документ doc = null; try {doc = reader.read (ins); element root = doc.getrootelement (); список <element> root.elements (); element e: list) {map.put (element> root.elements (); e.getText ());} return Map;} catch (documentException e1) {e1.printstacktrace ();} наконец {ins.close ();} return null;}3. Преобразование объекта текстового сообщения в XML
/ ** * Конвертировать объект текстового сообщения в XML * * @param TextMessage Объект текстового сообщения * @return Xml */ public Static String TextMessageToxml (TextMessage TextMessage) {xStream xstream = new Xstream (); xstream.alias ("xml", textmessage.getclass (); return xstream.alasmale);Выше приведено введение редактора в Java для реализации SpringMVC WeChat Access и реализации простой автоматической функции ответа. Я надеюсь, что это будет полезно для всех. Если у вас есть какие -либо вопросы, пожалуйста, оставьте мне сообщение, и редактор ответит всем вовремя. Большое спасибо за вашу поддержку сайту wulin.com!