近期学习android,需要访问服务器端数据,发现Android版的Hessian 地址:http://code.google.com/p/hessdroid/,很好用。这里把学习中的问题记下,备以后查询。
我在学习过程中,农民伯伯两篇博文对我帮助很大,具体内容不再赘述,需要了解点下面链接:
http://www.cnblogs.com/over140/archive/2010/07/30/1788563.html
http://www.cnblogs.com/over140/archive/2010/08/04/1792167.html
下面只说一下我遇到的问题,及解决办法!
1、servlet配置一定要写正确!
<servlet>
<servlet-name>hello</servlet-name><!-- 这个标签是定义的servlet的名字,和后面servlet-mapping--中的名字要一样!>
<servlet-class>com.BasicService</servlet-class><!--这是servlet调用的类名,注意包名-->
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern><!--这是客户端访问这个servlet时的名字-->
</servlet-mapping>
2、服务器端的BasicService可以有两种写法:
(1)BasicService继承HessianServlet,代码:
public class BasicService extends HessianServlet implements BasicAPI {
/**
*
*/
private static final long serialVersionUID = 1L;
private String _greeting = "Hello, World !";
public void setGreeting(String greeting)
{
_greeting = greeting;
}
public String hello()
{
return _greeting;
}
}
这时配置servlet使用上面问题1中的内容就可以,但是项目中必须导入Hessian官方Java的jar包,地址: http://hessian.caucho.com/,我使用的是hessian-4.0.7.jar。
(2)BasicService不继承HessianServlet,代码:
public class BasicService implements BasicAPI {
private String _greeting = "Hello, World !";
public void setGreeting(String greeting)
{
_greeting = greeting;
}
public String hello()
{
return _greeting;
}
}
此时servlet配置按照下面的写:
<web-app xmlns="http://caucho.com/ns/resin">
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>
<init-param>
<param-name>home-class</param-name>
<param-value>example.BasicService</param-value>
</init-param>
<init-param>
<param-name>home-api</param-name>
<param-value>example.BasicAPI</param-value>
</init-param>
</servlet>
<servlet-mapping>
<url-pattern>/hello</url-pattern>
<servlet-name>hello</servlet-name>
</servlet-mapping>
</web-app>
这个配置中指明了HessianSrvlet(红色标注部分)
两种方式都需要把hessian-4.0.7.jar服务器..\WEB-INF\lib下。
3、android客户端,String url = "http://localhost:8080/hessServer/hello";
这个url中不能使用localhost,因为android模拟器会把localhost当做它自己,而不是电脑的ip。可以在cmd中用ipconfig查一下你电脑连接外网的ip。
4、运行android程序,点击按钮时出现下面错误:
02-02 07:50:28.705: E/AndroidRuntime(433): FATAL EXCEPTION: main
02-02 07:50:28.705: E/AndroidRuntime(433): com.caucho.hessian.client.HessianRuntimeException: com.caucho.hessian.io.HessianProtocolException: expected hessian reply at 0x48 (H)
02-02 07:50:28.705: E/AndroidRuntime(433): H[1]��R
Hello, World !
02-02 07:50:28.705: E/AndroidRuntime(433): at com.caucho.hessian.client.HessianProxy.invoke(HessianProxy.java:235)
02-02 07:50:28.705: E/AndroidRuntime(433): at $Proxy0.hello(Native Method)
02-02 07:50:28.705: E/AndroidRuntime(433): at com.midgetnap.Hessian.HessianActivity$1.onClick(HessianActivity.java:37)
02-02 07:50:28.705: E/AndroidRuntime(433): at android.view.View.performClick(View.java:2408)
02-02 07:50:28.705: E/AndroidRuntime(433): at android.view.View$PerformClick.run(View.java:8816)
02-02 07:50:28.705: E/AndroidRuntime(433): at android.os.Handler.handleCallback(Handler.java:587)
02-02 07:50:28.705: E/AndroidRuntime(433): at android.os.Handler.dispatchMessage(Handler.java:92)
02-02 07:50:28.705: E/AndroidRuntime(433): at android.os.Looper.loop(Looper.java:123)
02-02 07:50:28.705: E/AndroidRuntime(433): at android.app.ActivityThread.main(ActivityThread.java:4627)
02-02 07:50:28.705: E/AndroidRuntime(433): at java.lang.reflect.Method.invokeNative(Native Method)
02-02 07:50:28.705: E/AndroidRuntime(433): at java.lang.reflect.Method.invoke(Method.java:521)
02-02 07:50:28.705: E/AndroidRuntime(433): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
02-02 07:50:28.705: E/AndroidRuntime(433): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
02-02 07:50:28.705: E/AndroidRuntime(433): at dalvik.system.NativeStart.main(Native Method)
02-02 07:50:28.705: E/AndroidRuntime(433): Caused by: com.caucho.hessian.io.HessianProtocolException: expected hessian reply at 0x48 (H)
02-02 07:50:28.705: E/AndroidRuntime(433): H[1]��RHello, World !
02-02 07:50:28.705: E/AndroidRuntime(433): at com.caucho.hessian.io.Hessian2Input.error(Hessian2Input.java:2705)
02-02 07:50:28.705: E/AndroidRuntime(433): at com.caucho.hessian.io.Hessian2Input.startReply(Hessian2Input.java:402)
02-02 07:50:28.705: E/AndroidRuntime(433): at com.caucho.hessian.client.HessianProxy.invoke(HessianProxy.java:221)
02-02 07:50:28.705: E/AndroidRuntime(433): ... 13 more
看这个错误,发现一个Hello,World !,说明服务器应该没错,查找好久,最后在http://code.google.com/p/hessdroid/上找到了一个和我出同样问题的人。解决办法只需要添加下面语句就可以。
factory.setHessian2Reply(false);
完整android端代码:
public class HessianActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String url = "http://.........:8080/hessServer/hello";
HessianProxyFactory factory = new HessianProxyFactory();
try {
factory.setDebug(true);
factory.setHessian2Reply(false);
factory.setReadTimeout(5000);
BasicAPI basic = (BasicAPI)factory.create(BasicAPI.class, url,getClassLoader());
Toast.makeText(HessianActivity.this, "调用结果:"+basic.hello(), Toast.LENGTH_LONG).show();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
});
}
}
andriod端需要导入hessdroid.jar(android版的hessian的jar文件),农民伯伯那有下载地址。