1 package com.foxinmy.weixin4j.socket;
2
3 import java.util.List;
4
5 import com.foxinmy.weixin4j.response.WeixinResponse;
6 import com.foxinmy.weixin4j.type.EncryptType;
7 import com.foxinmy.weixin4j.util.AesToken;
8 import com.foxinmy.weixin4j.util.HttpUtil;
9 import com.foxinmy.weixin4j.util.MessageUtil;
10 import com.foxinmy.weixin4j.util.ServerToolkits;
11
12 import io.netty.channel.ChannelHandler;
13 import io.netty.channel.ChannelHandlerContext;
14 import io.netty.handler.codec.MessageToMessageEncoder;
15 import io.netty.util.internal.logging.InternalLogger;
16 import io.netty.util.internal.logging.InternalLoggerFactory;
17
18
19
20
21
22
23
24
25
26
27
28
29 @ChannelHandler.Sharable
30 public class WeixinResponseEncoder extends MessageToMessageEncoder<WeixinResponse> {
31
32 protected final InternalLogger logger = InternalLoggerFactory.getInstance(getClass());
33
34 private final String XML_START = "<xml>";
35
36 private final String ELEMENT_TOUSERNAME = "<ToUserName><![CDATA[%s]]></ToUserName>";
37 private final String ELEMENT_FROMUSERNAME = "<FromUserName><![CDATA[%s]]></FromUserName>";
38 private final String ELEMENT_CREATETIME = "<CreateTime><![CDATA[%d]]></CreateTime>";
39 private final String ELEMENT_MSGTYPE = "<MsgType><![CDATA[%s]]></MsgType>";
40
41 private final String ELEMENT_MSGSIGNATURE = "<MsgSignature><![CDATA[%s]]></MsgSignature>";
42 private final String ELEMENT_ENCRYPT = "<Encrypt><![CDATA[%s]]></Encrypt>";
43 private final String ELEMENT_TIMESTAMP = "<TimeStamp><![CDATA[%s]]></TimeStamp>";
44 private final String ELEMENT_NONCE = "<Nonce><![CDATA[%s]]></Nonce>";
45 private final String XML_END = "</xml>";
46
47 @Override
48 protected void encode(ChannelHandlerContext ctx, WeixinResponse response, List<Object> out) {
49 WeixinMessageTransfer messageTransfer = ctx.channel().attr(ServerToolkits.MESSAGE_TRANSFER_KEY).get();
50 EncryptType encryptType = messageTransfer.getEncryptType();
51 StringBuilder content = new StringBuilder();
52 content.append(XML_START);
53 content.append(String.format(ELEMENT_TOUSERNAME, messageTransfer.getFromUserName()));
54 content.append(String.format(ELEMENT_FROMUSERNAME, messageTransfer.getToUserName()));
55 content.append(String.format(ELEMENT_CREATETIME, System.currentTimeMillis() / 1000l));
56 content.append(String.format(ELEMENT_MSGTYPE, response.getMsgType()));
57 content.append(response.toContent());
58 content.append(XML_END);
59 if (encryptType == EncryptType.AES) {
60 AesToken aesToken = messageTransfer.getAesToken();
61 String nonce = ServerToolkits.generateRandomString(32);
62 String timestamp = Long.toString(System.currentTimeMillis() / 1000l);
63 String encrtypt = MessageUtil.aesEncrypt(aesToken.getWeixinId(), aesToken.getAesKey(), content.toString());
64 String msgSignature = MessageUtil.signature(aesToken.getToken(), nonce, timestamp, encrtypt);
65 content.delete(0, content.length());
66 content.append(XML_START);
67 content.append(String.format(ELEMENT_NONCE, nonce));
68 content.append(String.format(ELEMENT_TIMESTAMP, timestamp));
69 content.append(String.format(ELEMENT_MSGSIGNATURE, msgSignature));
70 content.append(String.format(ELEMENT_ENCRYPT, encrtypt));
71 content.append(XML_END);
72 }
73 ctx.writeAndFlush(HttpUtil.createHttpResponse(content.toString(), ServerToolkits.CONTENTTYPE$APPLICATION_XML));
74 logger.info("{} encode weixin response:{}", encryptType, content);
75 }
76 }