mina的编码和解码以及断包的处理,发送自定义协议,仿qq聊天,发送xml或json和
tcp通讯对于java来说是很简单的。就是socket,也就是大家常说的套接字。大家不要把它看的很难。说白了tcp通讯其实就是数据流的读写。一条输入流,一条输出流。分别复杂发消息和接收消息。
明白了这些,ok,我们来看看我写的例子吧。先看服务器端的测试类的源码:
package com.minaqq.test; import com.minaqq.server.ServerMsgProtocol; import com.minaqq.worker.ServerSendMsgThread; public class MsgServerTest { public static void main(String[] args) { if(ServerMsgProtocol.serverStart()){ System.out.println("服务器启动成功......"); ServerSendMsgThread ssmt=new ServerSendMsgThread(); ssmt.start(); System.out.println("工作线程启动成功......"); } } }
服务端连接代码:
package com.minaqq.server; import java.io.IOException; import java.net.InetSocketAddress; import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.keepalive.KeepAliveFilter; import org.apache.mina.filter.keepalive.KeepAliveMessageFactory; import org.apache.mina.filter.keepalive.KeepAliveRequestTimeoutHandler; import org.apache.mina.filter.logging.LogLevel; import org.apache.mina.filter.logging.LoggingFilter; import org.apache.mina.transport.socket.SocketAcceptor; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; import com.minaqq.protocol.MsgProtocol; /** * @see 服务器启动类,字符串消息测试类 * @author Herman.Xiong * @date 2013年12月6日 09:23:31 * @file MinaServer.java * @package com.minaqq.server * @project MINA_QQ * @version 1.0 * @since jdk1.6,mina 2.0 */ public class ServerMsgProtocol { //30秒后超时 private static final int IDELTIMEOUT = 30; //15秒发送一次心跳包 private static final int HEARTBEATRATE = 15; private static SocketAcceptor acceptor; private ServerMsgProtocol() {} public static SocketAcceptor getAcceptor(){ if(null==acceptor){ // 创建非阻塞的server端的Socket连接 acceptor = new NioSocketAcceptor(); } return acceptor; } public static boolean serverStart() { DefaultIoFilterChainBuilder filterChain = getAcceptor().getFilterChain(); // 添加编码过滤器 处理乱码、编码问题 filterChain.addLast("codec", new ProtocolCodecFilter(new MsgProtocol())); LoggingFilter loggingFilter = new LoggingFilter(); loggingFilter.setMessageReceivedLogLevel(LogLevel.INFO); loggingFilter.setMessageSentLogLevel(LogLevel.INFO); // 添加日志过滤器 filterChain.addLast("loger", loggingFilter); // 设置核心消息业务处理器 getAcceptor().setHandler(new ServerMessageHandler()); //KeepAliveMessageFactory heartBeatFactory = new KeepAliveMessageFactoryImpl(); //KeepAliveRequestTimeoutHandler heartBeatHandler = new KeepAliveRequestTimeoutHandlerImpl(); //KeepAliveFilter heartBeat = new KeepAliveFilter(heartBeatFactory,IdleStatus.BOTH_IDLE, heartBeatHandler); // 是否回发 //heartBeat.setForwardEvent(false); // 发送频率 //heartBeat.setRequestInterval(HEARTBEATRATE); //getAcceptor().getFilterChain().addLast("heartbeat", heartBeat); getAcceptor().getSessionConfig().setReceiveBufferSize(2048*5000);//接收缓冲区1M getAcceptor().getSessionConfig().setBothIdleTime(30); //getAcceptor().getSessionConfig().setKeepAlive(true); // 设置session配置,30秒内无操作进入空闲状态 getAcceptor().getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, IDELTIMEOUT); try { // 绑定端口3456 getAcceptor().bind(new InetSocketAddress(8888)); return true; } catch (IOException e) { e.printStackTrace(); } return false; } }服务器的消息处理:
package com.minaqq.server; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.mina.core.future.CloseFuture; import org.apache.mina.core.future.IoFuture; import org.apache.mina.core.future.IoFutureListener; import org.apache.mina.core.service.IoHandler; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.core.session.IoSession; import com.minaqq.domain.MsgPack; /** * @see 处理服务器端消息 * @author Herman.Xiong * @date 2012-6-26 下午01:12:34 * @file ServerMessageHandler.java * @package com.minaqq.server * @project MINA_QQ * @version 1.0 * @since jdk1.6,mina 2.0 */ public class ServerMessageHandler implements IoHandler{ public void exceptionCaught(IoSession session, Throwable cause) throws Exception { System.out.println("服务器发生异常:"+ cause.toString()); } public void messageReceived(IoSession session, Object message) throws Exception { MsgPack mp=(MsgPack)message; System.out.println("收到客户端数据messageReceived----------:"+ mp.toString()); /*//请求协议 mp.setMsgMethod(3000); mp.setMsgPack("我是服务器发的消息"); mp.setMsgLength(mp.getMsgPack().getBytes().length); session.write(mp);*/ /*String content = mp.toString(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String datetime = sdf.format(new Date()); System.out.println(datetime+"服务器接收到数据的内容为messageReceived----------: " + content);*/ // 拿到所有的客户端Session /*Collection<IoSession> sessions = session.getService().getManagedSessions().values(); // 向所有客户端发送数据 for (IoSession sess : sessions) { sess.write(datetime + "\t" + content); }*/ } public void messageSent(IoSession session, Object message) throws Exception { /* System.out.println("服务器发送消息messageSent----------: "+ message); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String datetime = sdf.format(new Date()); System.out.println(datetime+"服务器发送消息messageSent----------: "+message.toString());*/ } public void sessionClosed(IoSession session) throws Exception { System.out.println("关闭当前session: "+session.getId()+session.getRemoteAddress()); CloseFuture closeFuture = session.close(true); closeFuture.addListener(new IoFutureListener<IoFuture>() { public void operationComplete(IoFuture future) { if (future instanceof CloseFuture) { ((CloseFuture) future).setClosed(); System.out.println("sessionClosed CloseFuture setClosed-->"+ future.getSession().getId()); } } }); } public void sessionCreated(IoSession session) throws Exception { System.out.println("创建一个新连接:"+ session.getRemoteAddress()+" id: "+session.getId()); session.write("welcome to the chat room !"); } public void sessionIdle(IoSession session, IdleStatus status) throws Exception { System.out.println("当前连接处于空闲状态:"+ session.getRemoteAddress()+ status); } public void sessionOpened(IoSession session) throws Exception { System.out.println("打开一个session id:"+ session.getId()+" 空闲连接个数IdleCount: "+ session.getBothIdleCount()); } }自定义协议类:
/** * @see 自定义协议 * @author Herman.Xiong * @date 2014年6月11日 10:30:40 */ public class MsgProtocol implements ProtocolCodecFactory{ private static final Charset charset=Charset.forName("UTF-8"); public ProtocolDecoder getDecoder(IoSession session) throws Exception { return new MsgProtocolDecoder(charset); } public ProtocolEncoder getEncoder(IoSession session) throws Exception { return new MsgProtocolEncoder(charset); } }协议解码类:
package com.minaqq.charset; import java.nio.ByteOrder; import java.nio.charset.Charset; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.CumulativeProtocolDecoder; import org.apache.mina.filter.codec.ProtocolDecoderOutput; import com.minaqq.domain.MsgPack; /** * @see 协议解码 * @author Herman.Xiong * @date 2014年6月11日 16:47:24 */ public class MsgProtocolDecoder extends CumulativeProtocolDecoder { private Charset charset=null; public MsgProtocolDecoder() { this(Charset.defaultCharset()); } public MsgProtocolDecoder(Charset charset) { this.charset = charset; } public void decode1(IoSession is, IoBuffer buf, ProtocolDecoderOutput out) throws Exception { buf.order(ByteOrder.LITTLE_ENDIAN); MsgPack mp=new MsgPack(); //获取消息的内容长度 mp.setMsgLength(buf.getInt()); //获取消息的功能函数 mp.setMsgMethod(buf.getInt()); byte[] msg=new byte[mp.getMsgLength()]; buf.get(msg); mp.setMsgPack(new String(msg,charset)); buf.flip(); out.write(mp); } public void dispose(IoSession arg0) throws Exception { } public void finishDecode(IoSession arg0, ProtocolDecoderOutput arg1) throws Exception { } public void decode0(IoSession arg0, IoBuffer arg1, ProtocolDecoderOutput arg2) throws Exception { int limit = arg1.limit(); byte[] bytes = new byte[limit]; arg1.get(bytes); arg2.write(bytes); } protected boolean doDecode(IoSession session, IoBuffer ioBuffer, ProtocolDecoderOutput out) throws Exception { ioBuffer.order(ByteOrder.LITTLE_ENDIAN); MsgPack mp = (MsgPack) session.getAttribute("nac-msg-pack"); // 从session对象中获取“xhs-upload”属性值 if(null==mp){ if (ioBuffer.remaining() >= 8) { //取消息体长度 int msgLength = ioBuffer.getInt(); int msgMethod = ioBuffer.getInt(); mp=new MsgPack(); mp.setMsgLength(msgLength); mp.setMsgMethod(msgMethod); session.setAttribute("nac-msg-pack",mp); return true; } return false; } if(ioBuffer.remaining()>=mp.getMsgLength()){ byte [] msgPack=new byte[mp.getMsgLength()]; ioBuffer.get(msgPack); mp.setMsgPack(new String(msgPack,charset)); session.removeAttribute("nac-msg-pack"); out.write(mp); return true; } return false; } }协议编码类:
package com.minaqq.charset; import java.io.NotSerializableException; import java.io.Serializable; import java.nio.ByteOrder; import java.nio.charset.Charset; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolDecoderOutput; import org.apache.mina.filter.codec.ProtocolEncoderAdapter; import org.apache.mina.filter.codec.ProtocolEncoderOutput; import com.minaqq.domain.MsgPack; public class MsgProtocolEncoder extends ProtocolEncoderAdapter{ private Charset charset=null; public MsgProtocolEncoder(Charset charset) { this.charset = charset; } //在此处实现对MsgProtocolEncoder包的编码工作,并把它写入输出流中 public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { if(message instanceof MsgPack){ MsgPack mp = (MsgPack) message; IoBuffer buf = IoBuffer.allocate(mp.getMsgLength()); buf.order(ByteOrder.LITTLE_ENDIAN); buf.setAutoExpand(true); //设置消息内容的长度 buf.putInt(mp.getMsgLength()); //设置消息的功能函数 buf.putInt(mp.getMsgMethod()); if (null != mp.getMsgPack()) { buf.put(mp.getMsgPack().getBytes(charset)); } buf.flip(); out.write(buf); out.flush(); buf.free(); } } public void dispose() throws Exception { } public void encode0(IoSession arg0, Object arg1, ProtocolEncoderOutput arg2) throws Exception { if (!(arg1 instanceof Serializable)) { throw new NotSerializableException(); } IoBuffer buf = IoBuffer.allocate(64); buf.setAutoExpand(true); buf.putObject(arg1); int objectSize = buf.position() - 4; if (objectSize > 1024) { throw new IllegalArgumentException("The encoded object is too big: " + objectSize + " (> " + 1024 + ')'); } buf.flip(); arg2.write(buf); } }协议实体类:
package com.minaqq.domain; import java.io.Serializable; /** * @see 自定义数据包 * @author Herman.Xiong * @date 2014年6月11日 11:31:45 */ public class MsgPack implements Serializable{ /** * 序列化和反序列化的版本号 */ private static final long serialVersionUID = 1L; //消息长度 private int msgLength; //消息方法 private int msgMethod; //消息包内容 private String msgPack; public MsgPack() {} public int getMsgLength() { return msgLength; } public void setMsgLength(int msgLength) { this.msgLength = msgLength; } public int getMsgMethod() { return msgMethod; } public void setMsgMethod(int msgMethod) { this.msgMethod = msgMethod; } public String getMsgPack() { return msgPack; } public void setMsgPack(String msgPack) { this.msgPack = msgPack; } public MsgPack(int msgLength, int msgMethod, String msgPack) { this.msgLength = msgLength; this.msgMethod = msgMethod; this.msgPack = msgPack; } public String toString() { return "MsgPack [msgLength=" + msgLength + ", msgMethod=" + msgMethod + ", msgPack=" + msgPack + "]"; } }心跳信息工厂类:
package com.minaqq.server; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.keepalive.KeepAliveMessageFactory; /** * @see 发送心跳包的内容 * getResponse()---->isResponse();获取数据判断心跳事件(目的是判断是否触发心跳超时异常) * isRequest()----->getRequest(); 写回数据是心跳事件触发的数据(目的写回给服务器(客户端)心跳包) * @author Herman.Xiong */ public class KeepAliveMessageFactoryImpl implements KeepAliveMessageFactory{ //心跳包内容 private static final String HEARTBEATREQUEST = "HEARTBEATREQUEST"; private static final String HEARTBEATRESPONSE = "HEARTBEATRESPONSE"; /** * @see 返回给客户端的心跳包数据 return 返回结果才是客户端收到的心跳包数据 * @author Herman.Xiong */ public Object getRequest(IoSession session) { return HEARTBEATREQUEST; } /** * @see 接受到的客户端数据包 * @author Herman.Xiong */ public Object getResponse(IoSession session, Object request) { return request; } /** * @see 判断是否是客户端发送来的的心跳包此判断影响 KeepAliveRequestTimeoutHandler实现类判断是否心跳包发送超时 * @author Herman.Xiong */ public boolean isRequest(IoSession session, Object message) { if(message.equals(HEARTBEATRESPONSE)){ System.out.println("接收到客户端心数据包引发心跳事件 心跳数据包是》》" + message); return true; } return false; } /** * @see 判断发送信息是否是心跳数据包此判断影响 KeepAliveRequestTimeoutHandler实现类 判断是否心跳包发送超时 * @author Herman.Xiong */ public boolean isResponse(IoSession session, Object message) { if(message.equals(HEARTBEATREQUEST)){ System.out.println("服务器发送数据包中引发心跳事件: " + message); return true; } return false; } }心跳业务处理类:
package com.minaqq.server; import org.apache.mina.core.future.CloseFuture; import org.apache.mina.core.future.IoFuture; import org.apache.mina.core.future.IoFutureListener; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.keepalive.KeepAliveFilter; import org.apache.mina.filter.keepalive.KeepAliveRequestTimeoutHandler; /** * @see 当心跳超时时的处理,也可以用默认处理 这里like * KeepAliveRequestTimeoutHandler.LOG的处理 * @author Herman.Xiong */ public class KeepAliveRequestTimeoutHandlerImpl implements KeepAliveRequestTimeoutHandler { /** * @see org.apache.mina.filter.keepalive.KeepAliveRequestTimeoutHandler心跳超时处理 * @author Herman.Xiong */ public void keepAliveRequestTimedOut(KeepAliveFilter filter, IoSession session) throws Exception { System.out.println("服务器端心跳包发送超时处理(即长时间没有发送(接受)心跳包)---关闭当前长连接"); CloseFuture closeFuture = session.close(true); closeFuture.addListener(new IoFutureListener<IoFuture>() { public void operationComplete(IoFuture future) { if (future instanceof CloseFuture) { ((CloseFuture) future).setClosed(); System.out.println("sessionClosed CloseFuture setClosed-->"+ future.getSession().getId()); } } }); } }服务器发送数据包的线程类:
package com.minaqq.worker; import java.util.Map; import org.apache.mina.core.session.IoSession; import com.minaqq.domain.MsgPack; import com.minaqq.server.ServerMsgProtocol; import com.minaqq.utils.XmlUtils; /** * @see 服务器端发送数据 * @author Herman.Xiong * @date 2014年6月9日 10:38:59 */ public class ServerSendMsgThread extends Thread{ public void run() { while(true){ if(null!=ServerMsgProtocol.getAcceptor()){ System.out.println("MinaServer.getAcceptor().getManagedSessionCount() is "+ServerMsgProtocol.getAcceptor().getManagedSessionCount()); Map<Long, IoSession> map=ServerMsgProtocol.getAcceptor().getManagedSessions(); for (Long key : map.keySet()) { IoSession is = map.get(key); //SocketAddress sa=is.getRemoteAddress(); //InetSocketAddress isa=(InetSocketAddress)sa; //is.write("我是中文测试"+"session id is "+key+" hostName:"+isa.getHostName()+" address:"+isa.getAddress()+" port:"+isa.getPort()+" isa.toString:"+isa.toString()); MsgPack mp=new MsgPack(); //请求协议 mp.setMsgMethod(1000); //mp.setMsgPack("我是服务端"); String str=""; for (int i = 0; i < 100; i++) { str+=XmlUtils.getXml(); } mp.setMsgPack(str); mp.setMsgLength(mp.getMsgPack().getBytes().length); try { is.write(mp); } catch (Exception e) { e.printStackTrace(); } } }else { System.out.println("MinaServer.getAcceptor is null "); } try { Thread.sleep(3000); } catch (Exception e) { e.printStackTrace(); } } } }客户端测试类:
package com.minaqq.test; import com.minaqq.client.ClientMsgProtocol; import com.minaqq.domain.MsgPack; import com.minaqq.worker.ClientSendMsgThread; public class MsgClientTest { public static void main(String[] args) { ClientMsgProtocol.clientStart(); System.out.println("客户端启动成功......"); ClientSendMsgThread csmt=new ClientSendMsgThread(); csmt.start(); /*MsgPack mp=new MsgPack(); //请求协议 mp.setMsgMethod(2000); mp.setMsgPack("我是客户端"); mp.setMsgLength(mp.getMsgPack().getBytes().length); ClientMsgProtocol.getIoSession().write(mp);*/ System.out.println("客户端工作线程启动成功......"); } }客户端创建连接类:
package com.minaqq.client; import java.net.InetSocketAddress; import org.apache.mina.core.future.ConnectFuture; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.logging.LogLevel; import org.apache.mina.filter.logging.LoggingFilter; import org.apache.mina.transport.socket.nio.NioSocketConnector; import com.minaqq.protocol.MsgProtocol; /** * @see 模拟客户端; * 用于连接服务端,并向服务端发送消息 * @author Herman.Xiong * @date 2013年11月26日 11:27:50 * @version 1.0 * @serial jdk 1.6 */ public class ClientMsgProtocol { private static NioSocketConnector connector ; private static IoSession is; public static NioSocketConnector getConnector(){ if(null==connector){ // 创建非阻塞的server端的Socket连接 connector = new NioSocketConnector(); } return connector; } public static IoSession getIoSession(){ return is; } public static void clientStart(){ // 创建客户端连接器 NioSocketConnector connector = getConnector(); connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new MsgProtocol())); LoggingFilter loggingFilter = new LoggingFilter(); loggingFilter.setMessageReceivedLogLevel(LogLevel.INFO); loggingFilter.setMessageSentLogLevel(LogLevel.INFO); connector.getFilterChain().addLast("logger", loggingFilter); connector.getSessionConfig().setReceiveBufferSize(2048*5000);//接收缓冲区1M connector.setConnectTimeoutMillis(30000); // 设置连接超时 connector.setHandler(new TimeClientHandler());// 设置消息处理器 ConnectFuture cf = connector.connect(new InetSocketAddress("10.10.2.136",8888));// 建立连接 cf.awaitUninterruptibly();// 等待连接创建完成 try { is=cf.getSession(); //getIoSession().write(new String(XmlUtils.getXml().getBytes("UTF-8")));// 发送消息 } catch (Exception e) { e.printStackTrace(); } } }客户端消息处理事件类:
package com.minaqq.client; import org.apache.mina.core.service.IoHandler; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.core.session.IoSession; import com.minaqq.domain.MsgPack; /** * @see 处理接收客户端消的息事件 * @author Herman.Xiong * @date 2013年11月26日 11:23:32 * @version 1.0 * @since jdk1.6 */ public class TimeClientHandler implements IoHandler{ /** * 接收客户端发送的消息 */ public void messageReceived(IoSession session, Object message) throws Exception { MsgPack mp=(MsgPack)message; System.out.println("收到服务端发来的消息:"+mp.toString());// 显示接收到的消息 } public void exceptionCaught(IoSession arg0, Throwable arg1) throws Exception { } public void messageSent(IoSession arg0, Object arg1) throws Exception { } public void sessionClosed(IoSession arg0) throws Exception { } public void sessionCreated(IoSession arg0) throws Exception { } public void sessionIdle(IoSession arg0, IdleStatus arg1) throws Exception { } public void sessionOpened(IoSession arg0) throws Exception { } }客户端发送消息线程类:
package com.minaqq.worker; import com.minaqq.client.ClientMsgProtocol; import com.minaqq.domain.MsgPack; /** * @see 模拟客户端发送数据 * @author Herman.Xiong * @date 2014年6月9日 10:38:59 */ public class ClientSendMsgThread extends Thread{ public void run() { while(true){ if(null!=ClientMsgProtocol.getConnector()){ try { //ClientMsgProtocol.getIoSession().write(new String("我是客户端".getBytes("UTF-8"))); MsgPack mp=new MsgPack(); //请求协议 mp.setMsgMethod(2000); mp.setMsgPack("我是客户端"); mp.setMsgLength(mp.getMsgPack().getBytes().length); ClientMsgProtocol.getIoSession().write(mp); } catch (Exception e) { e.printStackTrace(); } }else { System.out.println("MinaServer.getAcceptor is null "); } try { Thread.sleep(3000); } catch (Exception e) { e.printStackTrace(); } } } }发送xml消息的工具类:
package com.minaqq.utils; import com.minaqq.domain.Address; import com.minaqq.domain.House; import com.minaqq.domain.Person; import com.minaqq.domain.PhoneNumber; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.DomDriver; public class XmlUtils { public static void testXStream(){ XStream xstream=new XStream(new DomDriver()); xstream.alias("PERSON", Person.class); xstream.alias("ADDRESS",Address.class); xstream.alias("PHONENUMBER", PhoneNumber.class); xstream.alias("HOUSE", House.class); Person person=(Person)xstream.fromXML(XmlUtils.getXml()); System.out.println(person.toString()); } public static String getXml(){ StringBuffer sb=new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");// sb.append("<PERSON firstName=\"Herman\">"); sb.append("<lastName>Xiong</lastName> "); sb.append("<phonex>"); sb.append("<code>0</code>"); sb.append("<number>1234567</number>"); sb.append("</phonex>"); sb.append("<fax>"); sb.append("<code>0</code>"); sb.append("<number>7654321</number>"); sb.append("</fax>"); sb.append("<addList>"); sb.append("<ADDRESS>"); sb.append("<add>上海市</add>"); sb.append("<zipCode>123456</zipCode>"); sb.append("</ADDRESS>"); sb.append("</addList>"); sb.append("<house>"); sb.append("<HOUSE>"); sb.append("<size>300万</size>"); sb.append("<price>120平方米</price>"); sb.append("</HOUSE>"); sb.append("<HOUSE>"); sb.append("<size>500万</size>"); sb.append("<price>130平方米</price>"); sb.append("</HOUSE>"); sb.append("<HOUSE>"); sb.append("<size>160万</size>"); sb.append("<price>61.5平方米</price>"); sb.append("</HOUSE>"); sb.append("</house>"); sb.append("</PERSON>\n"); return sb.toString(); } }xml有关的实体类:
package com.minaqq.domain; import java.util.Arrays; import java.util.List; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; public class Person { @XStreamAsAttribute private String firstName; private String lastName; private PhoneNumber phonex; private PhoneNumber fax; private List<Address> addList; private House[] house; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public PhoneNumber getPhonex() { return phonex; } public void setPhonex(PhoneNumber phonex) { this.phonex = phonex; } public PhoneNumber getFax() { return fax; } public void setFax(PhoneNumber fax) { this.fax = fax; } public List<Address> getAddList() { return addList; } public void setAddList(List<Address> addList) { this.addList = addList; } public House[] getHouse() { return house; } public void setHouse(House[] house) { this.house = house; } public Person() { } public Person(String firstName, String lastName) { this.firstName=firstName; this.lastName=lastName; } public Person(String firstName, String lastName, PhoneNumber phonex, PhoneNumber fax) { this.firstName = firstName; this.lastName = lastName; this.phonex = phonex; this.fax = fax; } public Person(String firstName, String lastName, PhoneNumber phonex, PhoneNumber fax, List<Address> addList) { this.firstName = firstName; this.lastName = lastName; this.phonex = phonex; this.fax = fax; this.addList = addList; } public Person(String firstName, String lastName, PhoneNumber phonex, PhoneNumber fax, List<Address> addList, House[] house) { this.firstName = firstName; this.lastName = lastName; this.phonex = phonex; this.fax = fax; this.addList = addList; this.house = house; } @Override public String toString() { return "Person [addList=" + addList + ", fax=" + fax + ", firstName=" + firstName + ", house=" + Arrays.toString(house) + ", lastName=" + lastName + ", phonex=" + phonex + "]"; } }xml有关的实体类:
package com.minaqq.domain; public class Address { private String add; private String zipCode; public String getAdd() { return add; } public void setAdd(String add) { this.add = add; } public String getZipCode() { return zipCode; } public void setZipCode(String zipCode) { this.zipCode = zipCode; } public Address() { } public Address(String add, String zipCode) { this.add = add; this.zipCode = zipCode; } @Override public String toString() { return "Address [add=" + add + ", zipCode=" + zipCode + "]"; } }xml有关的实体类:
package com.minaqq.domain; public class PhoneNumber { private int code; private int number; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public PhoneNumber(){} public PhoneNumber(int code,int number){ this.code=code; this.number=number; } @Override public String toString() { return "PhoneNumber [code=" + code + ", number=" + number + "]"; } }xml有关的实体类:
package com.minaqq.domain; public class House { private String size; private String price; public String getSize() { return size; } public void setSize(String size) { this.size = size; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public House() { } public House(String size, String price) { this.size = size; this.price = price; } @Override public String toString() { return "House [price=" + price + ", size=" + size + "]"; } }
运行效果图,服务图片:
客户端图片:
OK,到此结束了,欢迎大家关注我的个人博客。学习资料已经源码下载请点击:http://download.csdn.net/download/xmt1139057136/7487611
如有不懂,请大家加入qq群:135430763共同学习!
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。