View Javadoc
1   package com.zone.weixin4j.service.impl;
2   
3   import com.zone.weixin4j.dispatcher.WeixinMessageDispatcher;
4   import com.zone.weixin4j.exception.HttpResponseException;
5   import com.zone.weixin4j.exception.MessageInterceptorException;
6   import com.zone.weixin4j.exception.WeixinException;
7   import com.zone.weixin4j.request.WeixinRequest;
8   import com.zone.weixin4j.response.SingleResponse;
9   import com.zone.weixin4j.response.WeixinResponse;
10  import com.zone.weixin4j.service.WxService;
11  import com.zone.weixin4j.socket.WeixinResponseEncoder;
12  import com.zone.weixin4j.type.EncryptType;
13  import com.zone.weixin4j.util.AesToken;
14  import com.zone.weixin4j.util.MessageUtil;
15  import com.zone.weixin4j.util.ServerToolkits;
16  import com.zone.weixin4j.xml.EncryptMessageHandler;
17  import org.apache.commons.logging.Log;
18  import org.apache.commons.logging.LogFactory;
19  import org.springframework.beans.factory.annotation.Autowired;
20  import org.springframework.context.annotation.DependsOn;
21  import org.springframework.stereotype.Component;
22  import org.springframework.util.StringUtils;
23  import org.springframework.web.bind.annotation.RequestMethod;
24  
25  import javax.servlet.http.HttpServletRequest;
26  
27  /**
28   * Created by Yz on 2017/3/14.
29   * WxServiceImpl
30   */
31  
32  @Component
33  @DependsOn({"weiXin4jContextAware", "weixinMessageDispatcher"})
34  public class WxServiceImpl implements WxService {
35  
36      private final Log logger = LogFactory.getLog(getClass());
37  
38      @Autowired
39      private WeixinMessageDispatcher messageDispatcher;
40  
41      @Autowired
42      private WeixinResponseEncoder weixinResponseEncoder;
43  
44      /**
45       * 处理Request
46       *
47       * @throws WeixinException
48       * @throws HttpResponseException
49       */
50      @Override
51      public WeixinResponse processRequest(String uri, String encrypt_type, String echostr, String timestamp, String nonce, String signature, String msg_signature, String messageContent, AesToken aesToken, HttpServletRequest request) throws WeixinException, HttpResponseException, MessageInterceptorException {
52          EncryptType encryptType = !StringUtils.isEmpty(encrypt_type) ? EncryptType.valueOf(encrypt_type.toUpperCase()) : EncryptType.RAW;
53          String encryptContent = null;
54          if (!ServerToolkits.isBlank(messageContent) && encryptType == EncryptType.AES) {
55              if (ServerToolkits.isBlank(aesToken.getAesKey())) {
56                  logger.error("EncodingAESKey not be empty in safety(AES) mode");
57              }
58              EncryptMessageHandler encryptHandler = EncryptMessageHandler.parser(messageContent);
59              encryptContent = encryptHandler.getEncryptContent();
60              /**
61               * 企业号第三方套件 ╮(╯_╰)╭
62               */
63              if (aesToken.getWeixinId().startsWith("tj")) {
64                  aesToken = new AesToken(encryptHandler.getToUserName(), aesToken.getToken(), aesToken.getAesKey());
65              }
66              messageContent = MessageUtil.aesDecrypt(aesToken.getWeixinId(), aesToken.getAesKey(), encryptContent);
67          }
68          WeixinRequest weixinRequest = new WeixinRequest(uri, encryptType, echostr, timestamp, nonce, signature, msg_signature, messageContent, encryptContent, aesToken).setHttpServletRequest(request);
69  
70          if (aesToken == null || (ServerToolkits.isBlank(weixinRequest.getSignature()) && ServerToolkits.isBlank(weixinRequest.getMsgSignature()))) {
71              throw new HttpResponseException(HttpResponseException.HttpResponseStatus.BAD_REQUEST);
72          }
73  
74          if (request.getMethod().equalsIgnoreCase(RequestMethod.GET.toString())) {
75              return doGet(weixinRequest);
76          } else if (request.getMethod().equalsIgnoreCase(RequestMethod.POST.toString())) {
77              return doPost(weixinRequest);
78          } else {
79              return otherwise(weixinRequest);
80          }
81      }
82  
83      /**
84       * 处理Get请求
85       *
86       * @throws WeixinException
87       * @throws HttpResponseException
88       */
89      protected WeixinResponse doGet(WeixinRequest request) throws WeixinException, HttpResponseException {
90          if (!ServerToolkits.isBlank(request.getSignature()) && MessageUtil.signature(request.getAesToken().getToken(), request.getTimeStamp(), request.getNonce()).equals(request.getSignature())) {
91              return new SingleResponse(request.getEchoStr());
92          }
93          // XML消息签名验证
94          if (!ServerToolkits.isBlank(request.getMsgSignature()) && MessageUtil.signature(request.getAesToken().getToken(), request.getTimeStamp(), request.getNonce(), request.getEchoStr()).equals(request.getMsgSignature())) {
95              return new SingleResponse(MessageUtil.aesDecrypt(null, request.getAesToken().getAesKey(), request.getEchoStr()));
96          }
97          throw new HttpResponseException(HttpResponseException.HttpResponseStatus.FORBIDDEN);
98      }
99  
100     /**
101      * 处理Post请求
102      *
103      * @throws WeixinException
104      * @throws HttpResponseException
105      */
106     protected WeixinResponse doPost(WeixinRequest request) throws HttpResponseException, MessageInterceptorException, WeixinException {
107         // URL参数签名验证
108         if (!ServerToolkits.isBlank(request.getSignature()) && !MessageUtil.signature(request.getAesToken().getToken(), request.getTimeStamp(), request.getNonce()).equals(request.getSignature())) {
109             throw new HttpResponseException(HttpResponseException.HttpResponseStatus.FORBIDDEN);
110         }
111         // XML消息签名验证
112         if (request.getEncryptType() == EncryptType.AES && !MessageUtil.signature(request.getAesToken().getToken(), request.getTimeStamp(), request.getNonce(), request.getEncryptContent()).equals(request.getMsgSignature())) {
113             throw new HttpResponseException(HttpResponseException.HttpResponseStatus.FORBIDDEN);
114         }
115         return messageDispatcher.doDispatch(request);
116     }
117 
118     protected WeixinResponse otherwise(WeixinRequest weixinRequest) throws HttpResponseException {
119         throw new HttpResponseException(HttpResponseException.HttpResponseStatus.METHOD_NOT_ALLOWED);
120     }
121 
122     public String transferResponse(WeixinResponse weixinResponse) throws WeixinException {
123         if(weixinResponse instanceof SingleResponse){
124             return weixinResponse.toContent();
125         } else {
126             return weixinResponseEncoder.encode(weixinResponse);
127         }
128     }
129 
130 }