이 기사에서는 WeChat에서 개발한 메시징 인터페이스를 살펴보겠습니다.
WeChat 개발은 WeChat 인터페이스를 호출하는 것이라고 생각하므로 읽고 호출해 보겠습니다. 예정된 작업이 없을 때 WeChat 인터페이스를 호출하려면 http get 및 post 요청을 보내야 하므로 get 및 post 요청을 구체적으로 보내려면 먼저 httputil 클래스를 작성하는 것이 가장 좋습니다. Java 네트워크 프로그래밍에서는 일부 코드를 Baidu하고 일부를 직접 캡슐화하면 정상적으로 사용할 수 있습니다.
import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.util.Iterator; import java.util.Map; import javax.activation.MimetypesFileTypeMap; /** * * @author luolei * */ public class HttpUtil { public static String httpGet(String httpUrl){ StringBuffer buffer = null; try{ URL url = new URL(httpUrl); HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection(); httpUrlConn.setDoInput(true); httpUrlConn.setRequestMethod("GET"); // 获取输入流 InputStream inputStream = httpUrlConn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); // 读取返回结果 buffer = new StringBuffer(); String str = null; while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } // 释放资源 bufferedReader.close(); inputStreamReader.close(); inputStream.close(); httpUrlConn.disconnect(); }catch(Exception e){ e.printStackTrace(); } return buffer.toString(); } /** * * 发 post 请求, */ public static String httpPost(String httpUrl,String data){ PrintWriter out = null; BufferedReader in = null; String result = ""; try { URL realUrl = new URL(httpUrl); // 打开和URL之间的连接 URLConnection conn = realUrl.openConnection(); // 设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流 out = new PrintWriter(conn.getOutputStream()); // 发送请求参数 out.print(data); // flush输出流的缓冲 out.flush(); // 定义BufferedReader输入流来读取URL的响应 in = new BufferedReader( new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送 POST 请求出现异常!"+e); e.printStackTrace(); } //使用finally块来关闭输出流、输入流 finally{ try{ if(out!=null){ out.close(); } if(in!=null){ in.close(); } } catch(IOException ex){ ex.printStackTrace(); } } return result; } /** * 上传图片 * * @param urlStr * @param textMap * @param fileMap * @return */ public static String formUpload(String urlStr, Map<String, String> textMap, Map<String, String> fileMap) { String res = ""; HttpURLConnection conn = null; String BOUNDARY = "---------------------------123821742118716"; //boundary就是request头和上传文件内容的分隔符 try { URL url = new URL(urlStr); conn = (HttpURLConnection) url.openConnection(); // System.out.println(conn); conn.setConnectTimeout(5000); conn.setReadTimeout(30000); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); conn.setRequestMethod("POST"); conn.setRequestProperty("Connection", "Keep-Alive"); conn .setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)"); conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); OutputStream out = new DataOutputStream(conn.getOutputStream()); // text if (textMap != null) { StringBuffer strBuf = new StringBuffer(); Iterator iter = textMap.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); String inputName = (String) entry.getKey(); String inputValue = (String) entry.getValue(); if (inputValue == null) { continue; } strBuf.append("\r\n").append("--").append(BOUNDARY).append( "\r\n"); strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"\r\n\r\n"); strBuf.append(inputValue); } out.write(strBuf.toString().getBytes()); } // file if (fileMap != null) { Iterator iter = fileMap.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); String inputName = (String) entry.getKey(); String inputValue = (String) entry.getValue(); if (inputValue == null) { continue; } File file = new File(inputValue); String filename = file.getName(); String contentType = new MimetypesFileTypeMap() .getContentType(file); if (filename.endsWith(".png")) { contentType = "image/png"; } if (contentType == null || contentType.equals("")) { contentType = "application/octet-stream"; } StringBuffer strBuf = new StringBuffer(); strBuf.append("\r\n").append("--").append(BOUNDARY).append( "\r\n"); strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"; filename=\"" + filename + "\"\r\n"); strBuf.append("Content-Type:" + contentType + "\r\n\r\n"); out.write(strBuf.toString().getBytes()); DataInputStream in = new DataInputStream( new FileInputStream(file)); int bytes = 0; byte[] bufferOut = new byte[1024]; while ((bytes = in.read(bufferOut)) != -1) { out.write(bufferOut, 0, bytes); } in.close(); } } byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes(); out.write(endData); out.flush(); out.close(); // 读取返回数据 StringBuffer strBuf = new StringBuffer(); BufferedReader reader = new BufferedReader(new InputStreamReader( conn.getInputStream())); String line = null; while ((line = reader.readLine()) != null) { strBuf.append(line).append("\n"); } res = strBuf.toString(); reader.close(); reader = null; } catch (Exception e) { System.out.println("发送POST请求出错。" + urlStr); e.printStackTrace(); } finally { if (conn != null) { conn.disconnect(); conn = null; } } return res; } }
그 중 httpGet과 httpPost가 사용됩니다. get 및 post 요청 보내기 WeChat 개발에서 메시지 인터페이스는 일반적으로 xml 형식이고, 기타 인터페이스에서 업로드하고 반환하는 데이터는 일반적으로 json이므로 json을 구문 분석하는 패키지가 필요합니다. gson을 사용할 수도 있습니다.
이제 메시지 인터페이스 테스트를 시작하겠습니다. 먼저 요청 프로세스를 이해해야 합니다.
WeChat 서버가 get 요청을 보냅니다. 입력된 URL을 기반으로 확인합니다. 확인이 성공하면 해당 URL을 기반으로 게시물 요청이 전송됩니다. 메시지 형식은 xml 형식입니다.
메시지 유형 개발 문서 네, 주로 다음과 같은 메시지가 있습니다. 텍스트, 사진, 음성뿐만 아니라 주의, 클릭, 점프와 같은 일부 이벤트도 포함됩니다.
이러한 메시지와 이벤트는 xml 형식이므로 xml 형식의 메시지를 파싱해야 합니다. dom4j를 사용하여 파싱합니다.
연결된 서블릿의 doPost 메서드는 이전에 확인되었습니다. 메시지를 파싱하기 위해
Liu Feng의 블로그에 작성된 방법을 따라 XML을 파싱하는 방법을 캡슐화하고 파싱된 결과를 map
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은 태그 이름(컨텐츠)에 따라 맵에 저장됩니다.
그런 다음 메시지 유형 msgType <🎜을 꺼낼 수 있음 >
String msgType = requestMap.get("MsgType") ;
그런 다음 메시지 유형을 결정합니다.
// 文本消息 if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) { request.getRequestDispatcher("TextMessage").forward(request, response); } // 图片消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) { request.getRequestDispatcher("ImageServlet").forward(request, response); } // 地理位置消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) { request.getRequestDispatcher("LocationServlet").forward(request, response); } // 链接消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) { request.getRequestDispatcher("LinkServlet").forward(request, response); } // 音频消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) { request.getRequestDispatcher("VedioServlet").forward(request, response); } // 事件推送 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) { // 事件类型 String eventType = requestMap.get("Event"); // 订阅 if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) { request.getRequestDispatcher("SubServlet").forward(request, response); } // 取消订阅 else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) { // TODO 取消订阅后用户再收不到公众号发送的消息,因此不需要回复消息 } // 自定义菜单点击事件 else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) { // TODO 自定义菜单权没有开放,暂不处理该类消息 request.getRequestDispatcher("ClickServlet").forward(request, response); } }
public class BaseMessageResp { // 接收方帐号(收到的OpenID) private String ToUserName; // 开发者微信号 private String FromUserName; // 消息创建时间 (整型) private long CreateTime; // 消息类型(text/music/news) private String MsgType; // 位0x0001被标志时,星标刚收到的消息 private int FuncFlag;
public class TextMessage extends BaseMessageResp { // 回复的消息内容 private String Content; public String getContent() { return Content; } public void setContent(String content) { Content = content; } }
/** * 文本消息对象转换成xml * * @param textMessage 文本消息对象 * @return xml */ public static String textMessageToXml(TextMessage textMessage) { xstream.alias("xml", textMessage.getClass()); return xstream.toXML(textMessage); }
위 내용은 WeChat에서 개발한 메시지 인터페이스의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!