微信公众平台+Java+新浪云(SinaAppEngine)快速接入方法

本文分享了使用新浪云接入微信公共平台的具体步骤与遇到的问题。作者通过实践解决了多个技术难题,包括servlet映射、版本兼容性及部署问题。

近期在完成移动web接入微信公共平台的工作。因为内测时便注册了新浪云的开发者,所以在接入时选择了新浪云作为首选。在参考了csdn柳峰的blog后,便动手弄了一下。

之前用Myeclipse开发较多,都采用的ssh的框架,考虑到接入的web不需要这么麻烦,所以希望采用servlet+jsp就完成基本功能。本以为这个过程会非常简单,谁知道却一波三折,耗费了2天的宝贵时间。总结原因是新浪云对开发的要求和细节描述不清楚。考虑到当前众多的云平台,这个案例有明显的代表性,能帮助大家完成相关的工作。

开发工具:

eclipse-jee-kepler-SR1-win32

前期失败的案例:

new了一个dynamic web project,module version选择了默认的3.0,项目建好后,按照柳峰的blog上http://blog.youkuaiyun.com/lyq8479/article/details/8944988中进行了相关工作,这里有个区别,他用的web.xml配置servlet,我直接就new了一个servlet,命名为CoreService,自动用annotation方式映射了。这时候会报错,从tomcat7中的lib文件夹,把servlet-api.jar拷贝到本地的lib中,编译通过。心想这不就ok了嘛,上传到SAE的应用中,访问该地址,擦,一点反映都没有,直接404了。

这时候就开始想着法儿解决此问题了:

1、是不是代码或编译有问题?

解决:本地tomcat7部署,运行,调试,一切ok。加了测试类后,验证字符串程序一切正常。给CoreService?signature=6be8ea46ee02efea9e99ebae5130b19b9e07c280&echostr=5980971381046308080&timestamp=1393224944&nonce=1392553418(这个是实际接入微信平台时,微信发过来的参数,可以从SAE应用的日志中看到),添加参数后,页面正常返回了echostr的5980971381046308080的字符串内容,这说明程序没有任何问题啊。

2、是servlet在SAE中映射有问题?

看了SAE新手指南和论坛的帖子后,发现很多人都有这个问题,但是没有一个说的仔细明了的。大致的方向,jdk版本要1.6的,服务器是jetty 7.4的,上传war包时需要去除可能引发冲突的servlet-api等jar。哎,真搞笑啊,SAE你大爷的,为啥不在关键位置把这些信息贴出来!!!

3、选择什么版本的jdk合适?

挑了个jre6 u45的版本,编译上传,发现还是错,看了看jvm的代码,错误显示为版本不合适。错误内容如下:

JAVA_SAE_Fatal_error: Unable to reach node goal: started
java.lang.UnsupportedClassVersionError: /CoreService : Unsupported major.minor version 51.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:740)

NND,难道让老子挨个去试?

这里还有个问题说明一下,之前从tomcat7中拷贝过来的servlet-api.jar不合适,需要换成servlet-api-2.5.jar。

这个问题的代表性在于:

本来采用的annotation映射servlet,我加入servlet-api-2.5.jar后,根本没发现jar中annotation的影子。这时候我料想到了问题的根源,得采用传统的web.xml配置方式。

这时候需要注意,module version 3.0 都是自动annotation,看样子必须降低module的版本了。


所以最终的解决方案出台了,请看:

1、new一个dynamic web project,module version选择了默认的2.2.

2、创建一个servlet

创建完成后,web.xml中会自动添加上对应的代码:

<servlet>
		<servlet-name>CoreService</servlet-name>
		<display-name>CoreService</display-name>
		<description></description>
		<servlet-class>com.bibang.core.CoreService</servlet-class>
</servlet>
	<servlet-mapping>
		<servlet-name>CoreService</servlet-name>
		<url-pattern>/CoreService</url-pattern>
	</servlet-mapping>


3、在CoreService.java中添加功能代码:

这里为了简便起见,省略了signature验证的环节,直接将echostr返回给了传递参数的服务器,代码如下:

package com.bibang.core;


import java.io.IOException;
import java.io.PrintWriter;


import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * Servlet implementation class CoreService
 */
public class CoreService extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public CoreService() {
        super();
        // TODO Auto-generated constructor stub
    }


	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 验证的相关代码,大家可以自己加上去
		String echostr = request.getParameter("echostr");
		PrintWriter out = response.getWriter();
		out.write(echostr);
		out.close();
		return;
	}


	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}


}



这里的buildpath为图中所示:


大家可以发现,现在jre版本为7,如果怕出错,可以改为jre6,不过我知道哪个版本最合适。

servlet-api-2.5.jar是我下载了jetty7.4.5的zip后,从中抽取的。jetty的下载地址:点击打开链接

4、打包成war,上传。

这时要把servlet-api-2.5.jar去掉!!!如果不小心忘记去掉了,那么后果是这样的:

HTTP ERROR 404

Problem accessing /CoreService. Reason:

    Servlet class com.bibang.core.CoreService is not a javax.servlet.Servlet
Caused by:

javax.servlet.UnavailableException: Servlet class com.bibang.core.CoreService is not a javax.servlet.Servlet
	at org.eclipse.jetty.servlet.ServletHolder.checkServletType(ServletHolder.java:354)
	at org.eclipse.jetty.servlet.ServletHolder.doStart(ServletHolder.java:240)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:58)
	at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:765)
	at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:245)
	at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1208)
	at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:586)
	at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:449)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:58)
	at org.eclipse.jetty.deploy.bindings.StandardStarter.processBinding(StandardStarter.java:36)
	at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:180)
	at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:482)
	at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:135)
	at org.eclipse.jetty.deploy.providers.ScanningAppProvider.fileChanged(ScanningAppProvider.java:154)
	at org.eclipse.jetty.deploy.providers.ScanningAppProvider$1.fileChanged(ScanningAppProvider.java:55)
	at org.eclipse.jetty.util.Scanner.reportChange(Scanner.java:655)
	at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:534)
	at org.eclipse.jetty.util.Scanner.scan(Scanner.java:394)
	at org.eclipse.jetty.util.Scanner$1.run(Scanner.java:345)
	at java.util.TimerThread.mainLoop(Timer.java:534)
	at java.util.TimerThread.run(Timer.java:484)

去掉上传的话,就是这样的:

java.lang.NullPointerException
	at org.eclipse.jetty.io.UncheckedPrintWriter.write(UncheckedPrintWriter.java:295)
	at com.sina.sae.facade.SaeServletPrintWriter.write(SaeServletPrintWriter.java:69)
	at com.bibang.core.CoreService.doGet(CoreService.java:31)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:538)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:478)
	at com.sina.sae.servlet.SaeServletHandler.doHandle(SaeServletHandler.java:49)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:517)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:225)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:937)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:406)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:871)
	at com.sina.sae.webapp.SaeWebAppContext.doScope(SaeWebAppContext.java:166)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:259)
	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:149)
	at com.sina.sae.handler.SaeUserInfoHandler.handle(SaeUserInfoHandler.java:106)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:110)
	at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:305)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:110)
	at org.eclipse.jetty.server.Server.handle(Server.java:346)
	at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:589)
	at org.eclipse.jetty.server.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:1048)
	at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:601)
	at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:214)
	at org.eclipse.jetty.server.HttpConnection.handle(HttpConnection.java:411)
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:535)
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:40)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:529)
	at java.lang.Thread.run(Thread.java:714)

这时候你也可以拿这个串试试效果

signature=6be8ea46ee02efea9e99ebae5130b19b9e07c280&echostr=5980971381046308080&timestamp=1393224944&nonce=1392553418

成功的话,页面会显示echostr的数字。

5、微信测试。

前面都正确了,你微信能接入不了?



评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值