`

Android中传送序列化对象出现的ClassNotFoundException解决办法

阅读更多

最近在做课程设计,老师要求是基于Android上的wifi通信的,之前没事的时候写过一个套接字编程的,完成了一个类似于聊天工具的功能。于是就想着改改,凑合着用用交上去。没想到在写的时候发现了一个很让人摸不着头脑的异常:ClassNotFoundException。

先说一下编码之前的思路,我想在PC上做服务端,在Android上做客户端,同时,在两端封装了RequestObject,ResponseObject等序列化的对象,用于在服务端和客户端之前传递请求和响应对象(通过ObjectInputStream和ObjectOutputStream),如下项目结构,可是在传送对象的时候发现了RequestObject出现了ClassNotFoundException,然后就直接无语中,明明服务端和客户端的RequestObject等用于传递进对象流的对象都是一模一样的,没道理找不到类啊。


经过一番尝试未果,索性把两个.java文件中唯一不一样的一行改掉,即为import xxx.xxx.xxx,我将两个项目中有关传递信息的model包的包名改为一样的。果然测试通过了,可能识别这种对象的时候,包名也是一个必要的因素吧。

问题虽然解决了,但是总觉得不方便,因为如果服务端这边的序列化对象要更改信息,势必客户端这边的对象也要改,同一次修改缺要改两遍信息,而且还很容易混淆,于是我又做了如下处理:新建了一个项目,用于保存有关任何需要传递的序列化对象,将这个项目导出.jar文件,再作为外部jar文件导入至客户端和服务端的项目里,这样就省去了很多工作,在正式往项目里添加操作之前,做了一个demo测试。


建立3个项目,分别是Android客户端,需要传递的数据,PC的服务端。分别编写好各个代码

 

/**
 * 2012-5-15
 * By WayneHu
 */
package pc.test;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;

import object.RequestObject;

public class MyServer {
	public static void main(String[] args) {
		try {
			ServerSocket server = new ServerSocket(10000);
			while (true) {
				System.out.println("Server is waiting...");
				Socket socket = server.accept();
				InputStream is;
				is = socket.getInputStream();
				ObjectInputStream ois = new ObjectInputStream(is);
				RequestObject request = (RequestObject) ois.readObject();
				System.out.println(request.getRequestClass());
				ois.close();
				is.close();
				socket.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
 

 

package android.test;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import object.RequestObject;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;

public class AndroidClientActivity extends Activity {
    /** Called when the activity is first created. */
	
	private EditText et_input;
	private String input;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        et_input = (EditText) findViewById(R.id.input);
    }
    
    public void onClick_send(View view) {
    	input = et_input.getText().toString();
    	RequestObject request = new RequestObject(1, input, null);
    	try {
			Socket socket = new Socket("10.0.2.2", 10000);
			OutputStream os = socket.getOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(os);
			oos.writeObject(request);
			oos.close();
			os.close();
			socket.close();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
    }
}

这里多说一句,在模拟器上的客户端,给PC上的服务端建立连接的时候,IP应为10.0.2.2

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

    <EditText
        android:id="@+id/input"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    
    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick_send"
        android:text="SEND" />
</LinearLayout>
 
/**
 * 2012-5-15
 * By WayneHu
 */
package object;

import java.io.Serializable;

public class RequestObject implements Serializable {
	public static final int LOGIN_REQUEST = 1;
	public static final int REGIST_REQUEST = 2;
	public static final int CHAT_REQUEST = 3;
	
	private int requestType;
	private String requestClass;
	private Object requestBody;
	
	/**
	 * @param requestType 请求类型
	 * @param requestClass 请求类名
	 * @param requestBody 请求对象
	 */
	public RequestObject(int requestType, String requestClass,
			Object requestBody) {
		super();
		this.requestType = requestType;
		this.requestClass = requestClass;
		this.requestBody = requestBody;
	}

	/**
	 * @return the requestType
	 */
	public int getRequestType() {
		return requestType;
	}

	/**
	 * @param requestType the requestType to set
	 */
	public void setRequestType(int requestType) {
		this.requestType = requestType;
	}

	/**
	 * @return the requestClass
	 */
	public String getRequestClass() {
		return requestClass;
	}

	/**
	 * @param requestClass the requestClass to set
	 */
	public void setRequestClass(String requestClass) {
		this.requestClass = requestClass;
	}

	/**
	 * @return the requestBody
	 */
	public Object getRequestBody() {
		return requestBody;
	}

	/**
	 * @param requestBody the requestBody to set
	 */
	public void setRequestBody(Object requestBody) {
		this.requestBody = requestBody;
	}
}

  然后在保存传递对象的项目那里导出JAR文件,如下图,然后分别在客户端项目和服务端项目右键选择构建路径-配置构建路径-添加外部JAR,选择之前导出的JAR文件,即可。


  

测试效果如下:



 

第一次写这么长的博客,用来记录自己学习路程的同时,也希望能帮助遇到同样问题的朋友。写的不好的地方欢迎朋友们提意见,写的有错的地方也希望各位大神能够不吝赐教。还是那句话,文明看帖,欢迎轻拍。

欢迎转载,转载请注明出处:

http://waynehu16.iteye.com/blog/1530760

  • 大小: 42.2 KB
  • 大小: 34 KB
  • 大小: 47.1 KB
  • 大小: 32.4 KB
1
0
分享到:
评论
2 楼 clq123clq 2014-07-22  
感谢啊,解决了我的问题
1 楼 清子123杨 2013-06-13  
还是看不明。。

相关推荐

    java 对象的序列化与反序列化

    Java对象的序列化和反序列化是Java编程中一项重要的技术,主要用于将对象的状态转换为字节流,以便存储或在网络上传输。这一过程对于理解Java的IO操作、持久化数据以及实现分布式通信等场景非常关键。 首先,我们来...

    ClassNotFoundException解决办法.md

    ClassNotFoundException解决办法.md

    Java对象的序列化和反序列化实践

    前者用于写入序列化对象,后者用于读取反序列化的对象。 **反序列化(Deserialization)** 1. **概念**:反序列化是将已序列化的字节流恢复为原来的Java对象的过程。 2. **过程**:通过`ObjectInputStream`的`...

    Socket通信之序列化对象通信

    在Java编程中,Socket通信是实现网络间进程通信的一种方式,而对象序列化则是将Java对象转换为字节流,以便在网络中传输或存储的重要技术。本教程将深入讲解如何结合Socket通信和对象序列化来实现在不同系统之间传递...

    用序列化(Serializable)保存、读取对象

    在Java编程语言中,序列化(Serializable)是一个关键特性,它允许对象的状态被持久化到磁盘上,或者在网络中进行传输。这个过程涉及到将一个对象转换为字节流,以便存储或传输,然后可以将这个字节流恢复为原始的...

    Java对象序列化的秘密

    3. **备份和恢复**: 对象序列化可以作为备份策略,当系统出现问题时,可以从序列化的数据中恢复。 4. **缓存**: 序列化可以将对象转化为字节流存储在内存中,提高缓存效率。 5. **跨进程通信(RMI)**: Remote ...

    序列化与反序列化Demo

    序列化与反序列化是计算机科学中的重要概念,特别是在数据存储、网络通信和持久化对象等领域。简单来说,序列化是将对象的状态转换为可存储或传输的数据格式的过程,而反序列化则是将这种数据格式恢复为原来的对象...

    java中的序列化与反序列化

    Java中的序列化与反序列化是Java编程语言中用于处理对象状态持久化和网络传输的重要技术。序列化是指将一个Java对象转换为字节流的过程,这样就可以将对象的状态保存到磁盘上或者通过网络传输。反序列化则是将字节流...

    Java序列化对象工具类 Eclipse工程(SerializUtil.zip)

    在实际开发中,特别是在需要持久化对象或者在网络间传递对象的场景下,`SerializUtil`这样的工具类是非常实用的。然而,需要注意的是,序列化可能导致安全问题,例如序列化后的对象可能会被恶意用户利用,因此在设计...

    Java中的序列化与反序列化.pdf

    上述工具类提供了序列化的方法`mySerialize()`,它接受一个对象和一个文件名作为参数,将对象序列化并保存到指定的文件中。 反序列化则是将字节流转换回原来的对象,这个过程可以通过`ObjectInputStream`类的`...

    ClassNotFoundException终极解决办法

    `ClassNotFoundException` 是 Java 开发过程中常见的运行时异常,通常发生在尝试加载某个类时,系统无法在指定的类路径(ClassPath)中找到对应的 `.class` 文件。本文将深入探讨 `ClassNotFoundException` 的原因、...

    自己写的一个序列化和反序列化的例子

    在代码中,你可以使用`ObjectOutputStream`来序列化对象。例如: ```java import java.io.*; class MySerializableClass implements Serializable { private String name; private int age; // 构造函数、...

    序列化、反序列化图文例子

    序列化和反序列化是计算机科学中的重要概念,特别是在数据存储、网络通信和持久化对象等领域。简单来说,序列化是将对象的状态转换为可存储或传输的数据格式,而反序列化则是将这些数据恢复为原来的对象状态。在这个...

    什么是Java的序列化和反序列化?如何实现对象的序列化和反序列化?(java面试题附答案).txt

    // 从文件中反序列化对象 Person deserializedPerson = deserializeObject("person.ser"); // 打印反序列化后的对象 System.out.println("Name: " + deserializedPerson.getName()); System.out.println("Age:...

    java程序,序列化和反序列化操作对文件的运用

    在Java编程语言中,序列化和反序列化是两种重要的技术,它们允许我们将对象的状态转换为字节流,以便存储到磁盘上或通过网络进行传输。这些技术在处理持久化数据、对象缓存以及跨进程通信(如RMI - 远程方法调用)时...

    Java序列化的机制和原理

    在这个例子中,我们首先定义了一个实现了`Serializable`接口的类`TestSerial`,然后通过`ObjectOutputStream`将对象序列化并写入文件,最后使用`ObjectInputStream`从文件中读取对象并反序列化。 #### 五、对象的...

    对象的序列化和反序列化

    为了将一个对象序列化到文件,我们可以使用`ObjectOutputStream`: ```java User user = new User(); user.setName("Alice"); user.setAge(25); try (FileOutputStream fos = new FileOutputStream("user.ser"); ...

Global site tag (gtag.js) - Google Analytics