1. 提供给客户端测试试题的Servlet程序IQTest代码:
package
com.Test;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.naming.InitialContext;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class IQTest extends HttpServlet ... {
/** *//**
*
*/
private static final long serialVersionUID = 6521059720875972304L;
protected static final String DBName = "java:/DefaultDS";
private DataSource dataSource;
//初始化数据库连接池
public void init(ServletConfig config) throws ServletException ...{
try ...{
InitialContext ic = new InitialContext();
//打开一个连接池
dataSource = (DataSource) ic.lookup(DBName);
} catch (Exception e) ...{
e.printStackTrace();
throw new ServletException("init error");
}
}
//处理Post申请
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException ...{
String question = null;
Connection c;
//设置为按字节传输
response.setContentType("application/octet-stream");
OutputStream os = response.getOutputStream();
//创建一个输出流对象
DataOutputStream dos = new DataOutputStream(os);
try ...{
c = dataSource.getConnection();
//获得问题的数目
PreparedStatement ps1 = c.prepareStatement("select count(*) as rowcount from iqquestion");
//执行查询
ResultSet rs1 = ps1.executeQuery();
rs1.next();
int num = rs1.getInt("rowcount");
rs1.close();
ps1.close();
//获得问题内容
PreparedStatement ps2 = c.prepareStatement("select * from iqquestion");
ResultSet rs2 = ps2.executeQuery();
//发送问题的数目
dos.writeInt(num);
System.out.println(num);
while (rs2.next()) ...{
question = rs2.getString("question");
System.out.println(question);
//发送问题的内容
dos.writeUTF(question);
}
//释放资源
rs2.close();
ps2.close();
c.close();
} catch (SQLException e) ...{
e.printStackTrace();
}
//设置发送的所有数据的流量属性
response.setContentLength(dos.size());
dos.close();
os.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException ...{
doPost(request, response);
}
}
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.naming.InitialContext;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class IQTest extends HttpServlet ... {
/** *//**
*
*/
private static final long serialVersionUID = 6521059720875972304L;
protected static final String DBName = "java:/DefaultDS";
private DataSource dataSource;
//初始化数据库连接池
public void init(ServletConfig config) throws ServletException ...{
try ...{
InitialContext ic = new InitialContext();
//打开一个连接池
dataSource = (DataSource) ic.lookup(DBName);
} catch (Exception e) ...{
e.printStackTrace();
throw new ServletException("init error");
}
}
//处理Post申请
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException ...{
String question = null;
Connection c;
//设置为按字节传输
response.setContentType("application/octet-stream");
OutputStream os = response.getOutputStream();
//创建一个输出流对象
DataOutputStream dos = new DataOutputStream(os);
try ...{
c = dataSource.getConnection();
//获得问题的数目
PreparedStatement ps1 = c.prepareStatement("select count(*) as rowcount from iqquestion");
//执行查询
ResultSet rs1 = ps1.executeQuery();
rs1.next();
int num = rs1.getInt("rowcount");
rs1.close();
ps1.close();
//获得问题内容
PreparedStatement ps2 = c.prepareStatement("select * from iqquestion");
ResultSet rs2 = ps2.executeQuery();
//发送问题的数目
dos.writeInt(num);
System.out.println(num);
while (rs2.next()) ...{
question = rs2.getString("question");
System.out.println(question);
//发送问题的内容
dos.writeUTF(question);
}
//释放资源
rs2.close();
ps2.close();
c.close();
} catch (SQLException e) ...{
e.printStackTrace();
}
//设置发送的所有数据的流量属性
response.setContentLength(dos.size());
dos.close();
os.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException ...{
doPost(request, response);
}
}
2. 客户端传过来的试题答案,客户姓名和编号的Servlet程序的IQAnswer代码:
package
com.Test;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import javax.naming.InitialContext;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
public class IQAnswer extends HttpServlet ... {
/** *//**
*
*/
private static final long serialVersionUID = -827875086373603144L;
protected static final String DBName = "java:/DefaultDS";
private DataSource dataSource;
//初始化数据库连接池
public void init(ServletConfig config) throws ServletException ...{
try ...{
InitialContext ic = new InitialContext();
//打开一个连接池
dataSource = (DataSource) ic.lookup(DBName);
} catch (Exception e) ...{
e.printStackTrace();
throw new ServletException("init error");
}
}
//处理Post申请
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException ...{
byte[] data = null;
InputStream iStrm = null;
iStrm = request.getInputStream();
int length = request.getContentLength();
if (length > 0) ...{ //如果存在传过来的数据
data = new byte[length];
iStrm.read(data);
}
//反序列化数据
Person person = new Person();
person.deserialize(data);
//向数据库添加数据
Connection c;
try ...{
c = dataSource.getConnection();
PreparedStatement ps = c.prepareStatement(
"insert into storeanswer values(?,?,?)");
ps.setString(1, person.get_userid());
ps.setString(2, person.get_name());
ps.setString(3, person.get_answer());
ps.executeUpdate();
ps.close();
c.close();
} catch (SQLException e) ...{
e.printStackTrace();
}
}
//处理Get请求
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException ...{
doPost(request, response);
}
}
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import javax.naming.InitialContext;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
public class IQAnswer extends HttpServlet ... {
/** *//**
*
*/
private static final long serialVersionUID = -827875086373603144L;
protected static final String DBName = "java:/DefaultDS";
private DataSource dataSource;
//初始化数据库连接池
public void init(ServletConfig config) throws ServletException ...{
try ...{
InitialContext ic = new InitialContext();
//打开一个连接池
dataSource = (DataSource) ic.lookup(DBName);
} catch (Exception e) ...{
e.printStackTrace();
throw new ServletException("init error");
}
}
//处理Post申请
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException ...{
byte[] data = null;
InputStream iStrm = null;
iStrm = request.getInputStream();
int length = request.getContentLength();
if (length > 0) ...{ //如果存在传过来的数据
data = new byte[length];
iStrm.read(data);
}
//反序列化数据
Person person = new Person();
person.deserialize(data);
//向数据库添加数据
Connection c;
try ...{
c = dataSource.getConnection();
PreparedStatement ps = c.prepareStatement(
"insert into storeanswer values(?,?,?)");
ps.setString(1, person.get_userid());
ps.setString(2, person.get_name());
ps.setString(3, person.get_answer());
ps.executeUpdate();
ps.close();
c.close();
} catch (SQLException e) ...{
e.printStackTrace();
}
}
//处理Get请求
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException ...{
doPost(request, response);
}
}
3. 把上面两个Servlet程序发布到JBoss服务器上,具体就是在web.xml文件中添加Servlet的XML信息
<
servlet
>
< servlet-name > IQAnswer </ servlet-name >
< servlet-class > com.Test.IQAnswer </ servlet-class >
</ servlet >
< servlet-mapping >
< servlet-name > IQAnswer </ servlet-name >
< url-pattern > /IQAnswer </ url-pattern >
</ servlet-mapping >
< servlet >
< servlet-name > IQTest </ servlet-name >
< servlet-class > com.Test.IQTest </ servlet-class >
</ servlet >
< servlet-mapping >
< servlet-name > IQTest </ servlet-name >
< url-pattern > /IQTest </ url-pattern >
</ servlet-mapping >
< servlet-name > IQAnswer </ servlet-name >
< servlet-class > com.Test.IQAnswer </ servlet-class >
</ servlet >
< servlet-mapping >
< servlet-name > IQAnswer </ servlet-name >
< url-pattern > /IQAnswer </ url-pattern >
</ servlet-mapping >
< servlet >
< servlet-name > IQTest </ servlet-name >
< servlet-class > com.Test.IQTest </ servlet-class >
</ servlet >
< servlet-mapping >
< servlet-name > IQTest </ servlet-name >
< url-pattern > /IQTest </ url-pattern >
</ servlet-mapping >
4. 客户端程序:
//
***********************************HttpIQTest.java
package chapter15;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
public class HttpIQTest extends MIDlet implements CommandListener ... {
private Display display;
private Form mainForm;
private Command exitCommand, connectCommand, backCommand, sendCommand;
private TextField useridField, usernameField;
private String userid, username;
public HttpIQTest() ...{
display = Display.getDisplay(this);
exitCommand = new Command("Exit", Command.EXIT, 1);
connectCommand = new Command("Connect", Command.SCREEN, 1);
backCommand = new Command("Back", Command.BACK, 1);
sendCommand = new Command("Send", Command.SCREEN, 1);
mainForm = new Form("服务器的信息");
useridField = new TextField("输入用户编号", null, 25, TextField.NUMERIC);
usernameField = new TextField("输入用户姓名", null, 25, TextField.ANY);
//收集界面上输入用户编号和姓名
mainForm.append(useridField);
mainForm.append(usernameField);
mainForm.addCommand(exitCommand);
mainForm.addCommand(connectCommand);
mainForm.setCommandListener(this);
}
protected void startApp() throws MIDletStateChangeException ...{
display.setCurrent(mainForm);
}
protected void pauseApp() ...{
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException ...{
}
public void commandAction(Command c, Displayable d) ...{
if (c == exitCommand) ...{
try ...{
destroyApp(false);
} catch (MIDletStateChangeException e) ...{
e.printStackTrace();
}
notifyDestroyed();
}
if (c == connectCommand) ...{
userid = useridField.getString();
username = usernameField.getString();
if(userid.length() == 0 && username.length() == 0) ...{
Alert a = new Alert("警告", "姓名和编号不能都为空", null, AlertType.ERROR);
a.setTimeout(Alert.FOREVER);
display.setCurrent(a);
return;
}
Thread t = new Thread() ...{
public void run() ...{
//访问服务器servlet
try ...{
getQuestion();
} catch (Exception e) ...{
System.out.println(e.toString());
}
}
};
t.start();
}
if (c == backCommand) ...{
display.setCurrent(mainForm);
}
if (c == sendCommand) ...{
Thread t = new Thread() ...{
public void run() ...{
try ...{
sendAnswer();
display.setCurrent(mainForm);
} catch (IOException e) ...{
System.out.println(e.toString());
}
}
};
t.start();
}
}
//联网获得测试内容
public void getQuestion() throws IOException ...{
HttpConnection conn = null;
InputStream iStrm = null;
String url = "http://127.0.0.1:8084/IQTest";
Form f;
f = new Form("请解答");
f.addCommand(backCommand);
f.addCommand(sendCommand);
f.setCommandListener(this);
try ...{
//创建httpconnection连接
conn = (HttpConnection) Connector.open(url);
conn.setRequestMethod(HttpConnection.POST);
//设置连接属性
conn.setRequestProperty("User-Agent", "Profile/MIDP-2.0 Configuration/CLDC-1.1");
conn.setRequestProperty("Content-Language", "en-US");
conn.setRequestProperty("Content-Type", "application/octet-stream");
conn.setRequestProperty("Accept", "application/octet-stream");
conn.setRequestProperty("Connection", "Keep-Alive");
//如果连接成功
if (conn.getResponseCode() == HttpConnection.HTTP_OK) ...{
iStrm = conn.openInputStream();
DataInputStream dis = new DataInputStream(iStrm);
//获得数据信息
int length = (int) conn.getLength();
if (length > 0) ...{
//读取传过来的题目数
int num = dis.readInt();
System.out.println(num);
String question;
for (int i = 0; i < num; i++) ...{
question = dis.readUTF();
//显示返回来的信息
f.append(new StringItem("第 " + i + " 题: ", question));
f.get(i).setLayout(Item.LAYOUT_EXPAND | Item.LAYOUT_NEWLINE_AFTER);
}
} else ...{
f.append("不能访问数据");
}
}
display.setCurrent(f);
} catch (Exception e) ...{
f.append("网络出错!");
System.out.println(e.toString());
} finally ...{
if (iStrm != null) ...{
iStrm.close();
}
if (conn != null) ...{
conn.close();
}
}
}
//发送答案
public void sendAnswer() throws IOException ...{
HttpConnection conn = null;
OutputStream oStrm = null;
String url = "http://127.0.0.1:8084/IQAnswer";
try ...{
//创建httpconnection连接
conn = (HttpConnection) Connector.open(url);
conn.setRequestMethod(HttpConnection.POST);
//设置连接属性
conn.setRequestProperty("User-Agent", "Profile/MIDP-2.0 Configuration/CLDC-1.1");
conn.setRequestProperty("Content-Language", "en-US");
conn.setRequestProperty("Content-Type", "application/octet-stream");
conn.setRequestProperty("Accept", "application/octet-stream");
conn.setRequestProperty("Connection", "Keep-Alive");
Person personIn = new Person(userid, username, "ABCDAB");//ABCDAB是答案
byte[] data = personIn.serialize();
conn.setRequestProperty("Content-Length", Integer.toString(data.length));
oStrm = conn.openOutputStream();
oStrm.write(data);
//提示答案成功发送
Alert a = new Alert("提示", "发送成功", null, AlertType.INFO);
a.setTimeout(Alert.FOREVER);
display.setCurrent(a);
} catch (Exception e) ...{
System.out.println(e.toString());
} finally ...{
if (oStrm != null) ...{
oStrm.close();
}
if (conn != null) ...{
conn.close();
}
}
}
}
// ******************************Person.java
package chapter15;
import java.io. * ;
import java.io.IOException;
public class Person implements KSerializable ... {
private String _name;
private String _answer;
private String _userid;
public Person() ...{
}
public Person(String userid, String name, String answer) ...{
_userid = userid;
_answer = answer;
_name = name;
}
public String get_answer() ...{
return _answer;
}
public void set_answer(String _answer) ...{
this._answer = _answer;
}
public String get_name() ...{
return _name;
}
public void set_name(String _name) ...{
this._name = _name;
}
public String get_userid() ...{
return _userid;
}
public void set_userid(String _userid) ...{
this._userid = _userid;
}
public byte[] serialize() throws IOException ...{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
DataOutputStream dout = new DataOutputStream(bout);
dout.writeUTF(_userid);
dout.writeUTF(_name);
dout.writeUTF(_answer);
return bout.toByteArray();
}
public void deserialize(byte[] data) throws IOException ...{
ByteArrayInputStream bin = new ByteArrayInputStream(data);
DataInputStream din = new DataInputStream(bin);
_userid = din.readUTF();
_name = din.readUTF();
_answer = din.readUTF();
}
}
// *****************************KSerializable.java
package chapter15;
import java.io.IOException;
public interface KSerializable ... {
byte[] serialize() throws IOException;
void deserialize(byte[] data) throws IOException;
}
package chapter15;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
public class HttpIQTest extends MIDlet implements CommandListener ... {
private Display display;
private Form mainForm;
private Command exitCommand, connectCommand, backCommand, sendCommand;
private TextField useridField, usernameField;
private String userid, username;
public HttpIQTest() ...{
display = Display.getDisplay(this);
exitCommand = new Command("Exit", Command.EXIT, 1);
connectCommand = new Command("Connect", Command.SCREEN, 1);
backCommand = new Command("Back", Command.BACK, 1);
sendCommand = new Command("Send", Command.SCREEN, 1);
mainForm = new Form("服务器的信息");
useridField = new TextField("输入用户编号", null, 25, TextField.NUMERIC);
usernameField = new TextField("输入用户姓名", null, 25, TextField.ANY);
//收集界面上输入用户编号和姓名
mainForm.append(useridField);
mainForm.append(usernameField);
mainForm.addCommand(exitCommand);
mainForm.addCommand(connectCommand);
mainForm.setCommandListener(this);
}
protected void startApp() throws MIDletStateChangeException ...{
display.setCurrent(mainForm);
}
protected void pauseApp() ...{
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException ...{
}
public void commandAction(Command c, Displayable d) ...{
if (c == exitCommand) ...{
try ...{
destroyApp(false);
} catch (MIDletStateChangeException e) ...{
e.printStackTrace();
}
notifyDestroyed();
}
if (c == connectCommand) ...{
userid = useridField.getString();
username = usernameField.getString();
if(userid.length() == 0 && username.length() == 0) ...{
Alert a = new Alert("警告", "姓名和编号不能都为空", null, AlertType.ERROR);
a.setTimeout(Alert.FOREVER);
display.setCurrent(a);
return;
}
Thread t = new Thread() ...{
public void run() ...{
//访问服务器servlet
try ...{
getQuestion();
} catch (Exception e) ...{
System.out.println(e.toString());
}
}
};
t.start();
}
if (c == backCommand) ...{
display.setCurrent(mainForm);
}
if (c == sendCommand) ...{
Thread t = new Thread() ...{
public void run() ...{
try ...{
sendAnswer();
display.setCurrent(mainForm);
} catch (IOException e) ...{
System.out.println(e.toString());
}
}
};
t.start();
}
}
//联网获得测试内容
public void getQuestion() throws IOException ...{
HttpConnection conn = null;
InputStream iStrm = null;
String url = "http://127.0.0.1:8084/IQTest";
Form f;
f = new Form("请解答");
f.addCommand(backCommand);
f.addCommand(sendCommand);
f.setCommandListener(this);
try ...{
//创建httpconnection连接
conn = (HttpConnection) Connector.open(url);
conn.setRequestMethod(HttpConnection.POST);
//设置连接属性
conn.setRequestProperty("User-Agent", "Profile/MIDP-2.0 Configuration/CLDC-1.1");
conn.setRequestProperty("Content-Language", "en-US");
conn.setRequestProperty("Content-Type", "application/octet-stream");
conn.setRequestProperty("Accept", "application/octet-stream");
conn.setRequestProperty("Connection", "Keep-Alive");
//如果连接成功
if (conn.getResponseCode() == HttpConnection.HTTP_OK) ...{
iStrm = conn.openInputStream();
DataInputStream dis = new DataInputStream(iStrm);
//获得数据信息
int length = (int) conn.getLength();
if (length > 0) ...{
//读取传过来的题目数
int num = dis.readInt();
System.out.println(num);
String question;
for (int i = 0; i < num; i++) ...{
question = dis.readUTF();
//显示返回来的信息
f.append(new StringItem("第 " + i + " 题: ", question));
f.get(i).setLayout(Item.LAYOUT_EXPAND | Item.LAYOUT_NEWLINE_AFTER);
}
} else ...{
f.append("不能访问数据");
}
}
display.setCurrent(f);
} catch (Exception e) ...{
f.append("网络出错!");
System.out.println(e.toString());
} finally ...{
if (iStrm != null) ...{
iStrm.close();
}
if (conn != null) ...{
conn.close();
}
}
}
//发送答案
public void sendAnswer() throws IOException ...{
HttpConnection conn = null;
OutputStream oStrm = null;
String url = "http://127.0.0.1:8084/IQAnswer";
try ...{
//创建httpconnection连接
conn = (HttpConnection) Connector.open(url);
conn.setRequestMethod(HttpConnection.POST);
//设置连接属性
conn.setRequestProperty("User-Agent", "Profile/MIDP-2.0 Configuration/CLDC-1.1");
conn.setRequestProperty("Content-Language", "en-US");
conn.setRequestProperty("Content-Type", "application/octet-stream");
conn.setRequestProperty("Accept", "application/octet-stream");
conn.setRequestProperty("Connection", "Keep-Alive");
Person personIn = new Person(userid, username, "ABCDAB");//ABCDAB是答案
byte[] data = personIn.serialize();
conn.setRequestProperty("Content-Length", Integer.toString(data.length));
oStrm = conn.openOutputStream();
oStrm.write(data);
//提示答案成功发送
Alert a = new Alert("提示", "发送成功", null, AlertType.INFO);
a.setTimeout(Alert.FOREVER);
display.setCurrent(a);
} catch (Exception e) ...{
System.out.println(e.toString());
} finally ...{
if (oStrm != null) ...{
oStrm.close();
}
if (conn != null) ...{
conn.close();
}
}
}
}
// ******************************Person.java
package chapter15;
import java.io. * ;
import java.io.IOException;
public class Person implements KSerializable ... {
private String _name;
private String _answer;
private String _userid;
public Person() ...{
}
public Person(String userid, String name, String answer) ...{
_userid = userid;
_answer = answer;
_name = name;
}
public String get_answer() ...{
return _answer;
}
public void set_answer(String _answer) ...{
this._answer = _answer;
}
public String get_name() ...{
return _name;
}
public void set_name(String _name) ...{
this._name = _name;
}
public String get_userid() ...{
return _userid;
}
public void set_userid(String _userid) ...{
this._userid = _userid;
}
public byte[] serialize() throws IOException ...{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
DataOutputStream dout = new DataOutputStream(bout);
dout.writeUTF(_userid);
dout.writeUTF(_name);
dout.writeUTF(_answer);
return bout.toByteArray();
}
public void deserialize(byte[] data) throws IOException ...{
ByteArrayInputStream bin = new ByteArrayInputStream(data);
DataInputStream din = new DataInputStream(bin);
_userid = din.readUTF();
_name = din.readUTF();
_answer = din.readUTF();
}
}
// *****************************KSerializable.java
package chapter15;
import java.io.IOException;
public interface KSerializable ... {
byte[] serialize() throws IOException;
void deserialize(byte[] data) throws IOException;
}