com.macrossx.wechat.servlet.WechatCoreServlet.java Source code

Java tutorial

Introduction

Here is the source code for com.macrossx.wechat.servlet.WechatCoreServlet.java

Source

/**
 * Copyright (C) 2016 X-Forever.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.macrossx.wechat.servlet;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import com.google.common.base.Charsets;
import com.google.common.hash.Hashing;
import com.google.inject.Singleton;
import com.macrossx.wechat.IWechatServer;
import com.macrossx.wechat.entity.server.WechatHttpEntity;
import com.macrossx.wechat.entity.server.WechatImageRequest;
import com.macrossx.wechat.entity.server.WechatLinkRequest;
import com.macrossx.wechat.entity.server.WechatLocationEventRequest;
import com.macrossx.wechat.entity.server.WechatLocationRequest;
import com.macrossx.wechat.entity.server.WechatMenuEventRequest;
import com.macrossx.wechat.entity.server.WechatQrsceneEventRequest;
import com.macrossx.wechat.entity.server.WechatSubscribeEventRequest;
import com.macrossx.wechat.entity.server.WechatTextRequest;
import com.macrossx.wechat.entity.server.WechatVideoRequest;
import com.macrossx.wechat.entity.server.WechatVoiceRequest;

import lombok.Data;
import lombok.extern.java.Log;

@Singleton
@Log
public class WechatCoreServlet extends HttpServlet {

    @Inject
    @Named("macrossx.wechat.token")
    private String wechatToken;

    @Inject
    private IWechatServer wechatServer;

    private static final long serialVersionUID = -5494799653006464275L;

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        try {
            if (checkSignature(req)) {
                resp.getWriter().write(req.getParameter("echostr"));
                resp.getWriter().flush();
                resp.getWriter().close();
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.info(e.getMessage());
        }

    }

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
        try {
            if (checkSignature(req)) {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                int i = -1;
                while ((i = req.getInputStream().read()) != -1) {
                    baos.write(i);
                }
                log.info(baos.toString());
                MessageType messageType = phraseXml(baos.toString(), MessageType.class);
                WechatHttpEntity entity = null;
                if (messageType != null) {
                    switch (messageType.getMsgType()) {
                    case "text": {
                        entity = wechatServer.onTextMessage(phraseXml(baos.toString(), WechatTextRequest.class));
                        break;
                    }
                    case "image": {
                        entity = wechatServer.onImageMessage(phraseXml(baos.toString(), WechatImageRequest.class));
                        break;
                    }
                    case "voice": {
                        entity = wechatServer.onVoiceMessage(phraseXml(baos.toString(), WechatVoiceRequest.class));
                        break;
                    }
                    case "video": {
                        entity = wechatServer.onVideoMessage(phraseXml(baos.toString(), WechatVideoRequest.class));
                        break;
                    }
                    case "shortvideo": {
                        entity = wechatServer
                                .onShortVideoMessage(phraseXml(baos.toString(), WechatVideoRequest.class));
                        break;
                    }
                    case "location": {
                        entity = wechatServer
                                .onLocationMessage(phraseXml(baos.toString(), WechatLocationRequest.class));
                        break;
                    }
                    case "link": {
                        entity = wechatServer.onLinkMessage(phraseXml(baos.toString(), WechatLinkRequest.class));
                        break;
                    }
                    case "event": {
                        switch (messageType.getEvent()) {
                        case "subscribe": {
                            entity = wechatServer.onEventSubscribe(
                                    phraseXml(baos.toString(), WechatSubscribeEventRequest.class));
                            break;
                        }
                        case "unsubscribe": {
                            entity = wechatServer.onEventUnsubscribe(
                                    phraseXml(baos.toString(), WechatSubscribeEventRequest.class));
                            break;
                        }
                        case "LOCATION": {
                            entity = wechatServer
                                    .onEventLocation(phraseXml(baos.toString(), WechatLocationEventRequest.class));
                            break;
                        }
                        case "SCAN": {
                            entity = wechatServer
                                    .onEventQrscene(phraseXml(baos.toString(), WechatQrsceneEventRequest.class));
                            break;
                        }
                        case "CLICK": {
                            entity = wechatServer
                                    .onEventMenu(phraseXml(baos.toString(), WechatMenuEventRequest.class));
                            break;
                        }
                        }
                        break;
                    }
                    }
                }
                System.out.println(entity);
                String result = phraseBean(entity);
                // log.info(result);
                resp.setContentType("text/html");
                resp.setCharacterEncoding("UTF-8");
                resp.getWriter().write(result);
                resp.getWriter().flush();
                resp.getWriter().close();
            }

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    private boolean checkSignature(final HttpServletRequest req) {
        // System.out.println(wechatToken);
        // System.out.println(req.getParameter("timestamp"));
        // System.out.println(req.getParameter("nonce"));
        // System.out.println(req.getParameter("signature"));
        String[] params = { wechatToken, req.getParameter("timestamp"), req.getParameter("nonce") };
        Arrays.sort(params);
        StringBuilder builder = new StringBuilder();
        for (String param : params) {
            builder.append(param);
        }
        return Hashing.sha1().hashString(builder.toString(), Charsets.UTF_8).toString()
                .equals(req.getParameter("signature"));

    }

    public static void main(String... s) throws NoSuchAlgorithmException, JAXBException {
        String sx = "<xml><ToUserName><![CDATA[gh_78f77fba606c]]></ToUserName><FromUserName><![CDATA[o707et_rh-zHWLHKaSa9nwTnCkNo]]></FromUserName><CreateTime>1462938545</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[ji]]></Content><MsgId>6283273207240019156</MsgId></xml>";
        // "<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1357290913</CreateTime><MsgType><![CDATA[voice]]></MsgType><MediaId><![CDATA[media_id]]></MediaId><Format><![CDATA[Format]]></Format><MsgId>1234567890123456</MsgId></xml>";
        JAXBContext context = JAXBContext.newInstance(MessageType.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        MessageType teype = (MessageType) unmarshaller.unmarshal(new StringReader(sx));
        System.out.println(teype);

        // String[] params = { "wechattest", "1462935386", "1150661839" };
        // Arrays.sort(params);
        // StringBuilder builder = new StringBuilder();
        // for (String param : params) {
        // builder.append(param);
        // }
        //
        // System.out.println(Hashing.sha1().hashString(builder.toString(),
        // Charsets.UTF_8).toString()
        // .equals("197ea60d62301ee8b881717342cc1c1335590e78"));

    }

    @SuppressWarnings("unchecked")
    public <T> T phraseXml(String xml, Class<T> clazz) {
        try {
            return (T) JAXBContext.newInstance(clazz).createUnmarshaller().unmarshal(new StringReader(xml));
        } catch (JAXBException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.info(e.getMessage());
        }
        return null;
    }

    private <T> String phraseBean(T t) {
        try {
            Marshaller marshaller = JAXBContext.newInstance(t.getClass()).createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");//
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            marshaller.marshal(t, output);
            return output.toString();
        } catch (JAXBException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.info(e.getMessage());
        }
        return "";
    }

    @XmlRootElement(name = "xml")
    @Data
    public static class MessageType {
        @XmlElement(name = "MsgType")
        private String MsgType;
        @XmlElement(name = "Event")
        private String Event;
    }
}