netty5.0版本的,简单的一个例子,用于学习交流,废话不多说,直接上代码;
一,pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.dingw</groupId> <artifactId>testNetty-Http-Xml</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>testNetty-Http-Xml Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.3</version> <scope>provided</scope> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>5.0.0.Alpha2</version> </dependency> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>3.0.0-alpha-2</version> </dependency> <dependency> <groupId>com.jcraft</groupId> <artifactId>jzlib</artifactId> <version>1.1.3</version> <scope>runtime</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2.1-b03</version> </dependency> <dependency> <groupId>com.barchart.udt</groupId> <artifactId>barchart-udt-core</artifactId> <version>2.3.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.jibx/jibx-bind --> <dependency> <groupId>org.jibx</groupId> <artifactId>jibx-bind</artifactId> <version>1.2.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.jibx.schema.org.jibx/org.jibx.schema.org.jibx.sampleschema.address --> <dependency> <groupId>org.jibx.schema.org.jibx</groupId> <artifactId>org.jibx.schema.org.jibx.sampleschema.address</artifactId> <version>1.1.4</version> </dependency> <!-- https://mvnrepository.com/artifact/org.jibx/maven-jibx-plugin --> <dependency> <groupId>org.jibx</groupId> <artifactId>maven-jibx-plugin</artifactId> <version>1.3.1</version> </dependency> <!-- https://mvnrepository.com/artifact/com.thoughtworks.xstream/xstream --> <dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.10</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>netty</finalName> </build> </project>
一.实体类(这里XML与javabean之间的转换用的XStream)
package com.dingw.bean; import com.thoughtworks.xstream.annotations.XStreamAlias; /** * @Author Dingwei * @Date 2018/1/14 22:11 * @ClassName Address * @Description */ @XStreamAlias("billTo") public class Address { private String street1; private String street2; private String city; private String state; private String postCode; private String country; public String getStreet1() { return street1; } public void setStreet1(String street1) { this.street1 = street1; } public String getStreet2() { return street2; } public void setStreet2(String street2) { this.street2 = street2; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getState() { return state; } public void setState(String state) { this.state = state; } public String getPostCode() { return postCode; } public void setPostCode(String postCode) { this.postCode = postCode; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } @Override public String toString() { return "Address [street1=" + street1 + ", street2=" + street2 + ", city=" + city + ", state=" + state + ", postCode=" + postCode + ", country=" + country + "]"; } }package com.dingw.bean; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; import java.util.List; /** * @Author Dingwei * @Date 2018/1/14 22:09 * @ClassName Customer * @Description */ public class Customer { @XStreamAsAttribute private long customerNumber; private String firstName; private String lastName; private List<String> middleNames; public long getCustomerNumber() { return customerNumber; } public void setCustomerNumber(long customerId) { this.customerNumber = customerId; } 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 List<String> getMiddleNames() { return middleNames; } public void setMiddleNames(List<String> middleNames) { this.middleNames = middleNames; } @Override public String toString() { return "Customer [customerNumber=" + customerNumber + ", firstName=" + firstName + ", lastName=" + lastName + ", middleNames=" + middleNames + "]"; } }package com.dingw.bean; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; /** * @Author Dingwei * @Date 2018/1/14 22:06 * @ClassName Order * @Description */ @XStreamAlias("order") public class Order { @XStreamAsAttribute private long orderNumber; private Customer customer; private Address billTo; private Shipping shipping; private Address shipTo; @XStreamAsAttribute private Float total; public long getOrderNumber() { return orderNumber; } public void setOrderNumber(long orderId) { this.orderNumber = orderId; } public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; } public Address getBillTo() { return billTo; } public void setBillTo(Address billTo) { this.billTo = billTo; } public Shipping getShipping() { return shipping; } public void setShipping(Shipping shipping) { this.shipping = shipping; } public Address getShipTo() { return shipTo; } public void setShipTo(Address shipTo) { this.shipTo = shipTo; } public Float getTotal() { return total; } public void setTotal(Float total) { this.total = total; } @Override public String toString() { return "Order [orderNumber=" + orderNumber + ", customer=" + customer + ", billTo=" + billTo + ", shipping=" + shipping.toString() + ", shipTo=" + shipTo + ", total=" + total + "]"; } }package com.dingw.bean; /** * @Author Dingwei * @Date 2018/1/14 22:13 * @ClassName Shipping * @Description */ public enum Shipping { STANDARD_MALL,PRIORITY_MALL,INTERNATIONAL_MAIL,DOMESTIC_EXPRESS, INTERANATIONAL_EXPRESS }package com.dingw.bean; /** * @Author Dingwei * @Date 2018/1/15 9:54 * @ClassName OrderFactory * @Description */ public class OrderFactory { public static Order create(long orderID) { Order order = new Order(); order.setOrderNumber(orderID); order.setTotal(9999.999f); Address address = new Address(); address.setCity("南京市"); address.setCountry("中国"); address.setPostCode("123321"); address.setState("江苏省"); address.setStreet1("龙眠大道"); order.setBillTo(address); Customer customer = new Customer(); customer.setCustomerNumber(orderID); customer.setFirstName("李"); customer.setLastName("林峰"); order.setCustomer(customer); order.setShipping(Shipping.INTERNATIONAL_MAIL); order.setShipTo(address); return order; } }
二.客户端启动类
package com.dingw.bean; import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestEncoder; import io.netty.handler.codec.http.HttpResponseDecoder; import java.net.InetSocketAddress; /** * @Author Dingwei * @Date 2018/1/15 9:51 * @ClassName HttpXmlClient * @Description */ public class HttpXmlClient { public void connect(int port) throws Exception { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { // xml解码器 ch.pipeline().addLast("http-decoder", new HttpResponseDecoder()); ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(65536)); ch.pipeline().addLast("xml-decoder", new HttpXmlResponseDecoder(Order.class, true)); ch.pipeline().addLast("http-encoder", new HttpRequestEncoder()); // xml编码器 ch.pipeline().addLast("xml-encoder", new HttpXmlRequestEncoder()); ch.pipeline().addLast("xmlClientHandler", new HttpXmlClientHandle()); } }); ChannelFuture f = b.connect(new InetSocketAddress(port)).sync(); f.channel().closeFuture().sync(); } finally { group.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = 8080; if (args != null && args.length > 0) { try { port = Integer.valueOf(args[0]); } catch (NumberFormatException e) { } } new HttpXmlClient().connect(port); } }三.客户端handlerpackage com.dingw.bean; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.FullHttpResponse; /** * @Author Dingwei * @Date 2018/1/15 9:53 * @ClassName HttpXmlClientHandle * @Description */ public class HttpXmlClientHandle extends SimpleChannelInboundHandler<HttpXmlResponse> { @Override public void channelActive(ChannelHandlerContext ctx) { // 给客户端发送请求消息,HttpXmlRequest包含FullHttpRequest和Order这个了类 HttpXmlRequest request = new HttpXmlRequest(null, OrderFactory.create(123)); ctx.writeAndFlush(request); System.out.println("客户端:向服务端发送消息完成"); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.getMessage(); cause.printStackTrace(); ctx.close(); } @Override protected void messageReceived(ChannelHandlerContext ctx, HttpXmlResponse msg) throws Exception { System.out.println("接收到服务端的响应"); System.out.println("The client receive response of http header is : " + msg.getFullHttpResponse().headers().names()); System.out.println("The client receive response of http body is : " + msg.getResult()); } }四.服务端启动类package com.dingw.bean; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.codec.http.HttpResponseEncoder; import java.net.InetSocketAddress; /** * @Author Dingwei * @Date 2018/1/15 9:59 * @ClassName HttpXmlServer * @Description */ public class HttpXmlServer { public void run(final int port) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast("http-decoder", new HttpRequestDecoder()); ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(65536)); ch.pipeline().addLast("xml-decoder", new HttpXmlRequestDecoder(Order.class, true)); ch.pipeline().addLast("http-encoder", new HttpResponseEncoder()); ch.pipeline().addLast("xml-encoder", new HttpXmlResponseEncoder()); ch.pipeline().addLast("xmlServerHandler", (ChannelHandler) new HttpXmlServerHandler()); } }); ChannelFuture future = b.bind(new InetSocketAddress(port)).sync(); System.out.println("HTTP订购服务器启动,网址是 : " + "http://localhost:" + port); future.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = 8080; if (args.length > 0) { try { port = Integer.parseInt(args[0]); } catch (NumberFormatException e) { e.printStackTrace(); } } new HttpXmlServer().run(port); } }五.服务端handlerpackage com.dingw.bean; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.util.CharsetUtil; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import java.util.ArrayList; import java.util.List; import static io.netty.handler.codec.http.HttpHeaderNames.CONNECTION; import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE; import static io.netty.handler.codec.http.HttpHeaderValues.KEEP_ALIVE; import static io.netty.handler.codec.http.HttpResponseStatus.INTERNAL_SERVER_ERROR; import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; /** * @Author Dingwei * @Date 2018/1/15 10:01 * @ClassName HttpXmlServerHandler * @Description */ public class HttpXmlServerHandler extends SimpleChannelInboundHandler<HttpXmlRequest> { @Override public void messageReceived(final ChannelHandlerContext ctx, HttpXmlRequest xmlRequest) throws Exception { System.out.println("服务端接收到客户端发送过来的数据"); HttpRequest request = xmlRequest.getRequest(); Order order = (Order) xmlRequest.getBody(); // 输出解码获得的Order对象 System.out.println("Http server receive request : " + order); dobusiness(order); System.out.println(order); //向客户端发送应答消息 System.out.println("服务端向客户端:开始响应数据"); ChannelFuture future = ctx.writeAndFlush(new HttpXmlResponse(null, order)); System.out.println("服务端向客户端:响应数据完成"); if (request.headers().get(CONNECTION) != KEEP_ALIVE) { future.addListener(new GenericFutureListener<Future<? super Void>>() { public void operationComplete(Future future) throws Exception { ctx.close(); } }); } } private void dobusiness(Order order) { order.getCustomer().setFirstName("狄"); order.getCustomer().setLastName("仁杰"); List<String> midNames = new ArrayList<String>(); midNames.add("李元芳"); order.getCustomer().setMiddleNames(midNames); Address address = order.getBillTo(); address.setCity("洛阳"); address.setCountry("大唐"); address.setState("河南道"); address.setPostCode("123456"); order.setBillTo(address); order.setShipTo(address); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); // 在链路没有关闭并且出现异常的时候发送给客户端错误信息 if (ctx.channel().isActive()) { sendError(ctx, INTERNAL_SERVER_ERROR); } } private static void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) { FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, status, Unpooled.copiedBuffer("失败: " + status.toString() + "\r\n", CharsetUtil.UTF_8)); response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8"); ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } }六.所有的编解码类及请求和响应对象的封装类(都有注解就不区分说明了)package com.dingw.bean; import io.netty.handler.codec.http.FullHttpRequest; /** * @Author Dingwei * @Date 2018/1/15 9:54 * @ClassName HttpXmlRequest * @Description 封装一个HttpXml请求对象 */ public class HttpXmlRequest { /** * 两个成员变量FullHttpRequest和编码对象Object,用于实现和协议栈之间的解耦 */ private FullHttpRequest request; private Object body; public HttpXmlRequest(FullHttpRequest request, Object body) { this.request = request; this.body = body; } public final FullHttpRequest getRequest() { return request; } public final void setRequest(FullHttpRequest request) { this.request = request; } public final Object getBody() { return body; } public final void setBody(Object body) { this.body = body; } @Override public String toString() { return "HttpXmlRequest [request=" + request + ", body =" + body + "]"; } }package com.dingw.bean; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.util.CharsetUtil; import java.util.List; import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE; import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST; import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; /** * @Author Dingwei * @Date 2018/1/15 10:00 * @ClassName HttpXmlRequestDecoder * @Description 请求消息解码器,HTTP服务器接收到 http+xml请求消息后,需要从HTTP消息体获取请求码流,然后反序列化,得到实体对象和HTTP消息头 */ public class HttpXmlRequestDecoder extends AbstractHttpXmlDecoder<FullHttpRequest> { public HttpXmlRequestDecoder(Class<?> clazz) { this(clazz, false); } public HttpXmlRequestDecoder(Class<?> clazz, boolean isPrint) { super(clazz, isPrint); } @Override protected void decode(ChannelHandlerContext arg0, FullHttpRequest arg1, List<Object> arg2) throws Exception { // 对HTTP请求消息本身的解码结果进行判断,如果已经解码失败,再对消息体进行二次解码已经没有意义 if (!arg1.decoderResult().isSuccess()) { sendError(arg0, BAD_REQUEST); return; } // 通过HttpsdXmlRequest和反序列化后的Order对象构造HttpXmlRequest实例 HttpXmlRequest request = new HttpXmlRequest(arg1, decode0(arg0, arg1.content())); // 将请求交给下一个解码器处理 arg2.add(request); } private static void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) { FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, status, Unpooled.copiedBuffer("Failure: " + status.toString() + "\r\n", CharsetUtil.UTF_8)); response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8"); ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } }package com.dingw.bean; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.http.*; import java.net.InetAddress; import java.util.List; /** * @Author Dingwei * @Date 2018/1/15 9:54 * @ClassName HttpXmlRequestEncoder * @Description 请求消息编码类 */ public class HttpXmlRequestEncoder extends AbstractHttpXmlEncoder<HttpXmlRequest> { @Override protected void encode(ChannelHandlerContext ctx, HttpXmlRequest msg, List<Object> out) throws Exception { // 调用父类的encode0方法将Order对象转换为xml字符串,并将其封装为ByteBuf ByteBuf body = encode0(ctx, msg.getBody()); FullHttpRequest request = msg.getRequest(); System.out.println("encode0方法将Order对象转换为xml字符串,并将其封装为ByteBuf"+request); // 对请求消息头进行判断,如果业务层自定义和定制了消息头,则使用自定义的,如request为空,则新建一个FullHttpRequest对象,并将设置消息头 if (request == null) { // 在构造方法中,将body设置为请求消息体 request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/do", body); HttpHeaders headers = request.headers(); // 表示请求的服务器网址 headers.set(HttpHeaderNames.HOST, InetAddress.getLocalHost().getHostAddress()); // Connection表示客户端与服务连接类型;Keep-Alive表示长连接;CLOSE表示短连接 // header中包含了值为close的connection,都表明当前正在使用的tcp链接在请求处理完毕后会被断掉。 // 以后client再进行新的请求时就必须创建新的tcp链接了。 headers.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE); // 浏览器支持的压缩编码是 gzip 和 deflate headers.set(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.GZIP.toString() + ',' + HttpHeaderValues.DEFLATE.toString()); // 浏览器支持的解码集 headers.set(HttpHeaderNames.ACCEPT_CHARSET, "ISO-8859-1,utf-8;q=0.7,*;q=0.7"); // 浏览器支持的语言 headers.set(HttpHeaderNames.ACCEPT_LANGUAGE, "zh"); // 使用的用户代理是 Netty xml Http Client side headers.set(HttpHeaderNames.USER_AGENT, "Netty xml Http Client side"); // 浏览器支持的 MIME类型,优先顺序为从左到右 headers.set(HttpHeaderNames.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); } /** * 由于HTTP请求消息体不能为空,也没有使用chunk方式,所以要在Http消息投中设置消息体长度CONTENT_LENGTH */ request.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, body.readableBytes()); // 将请求消息添加进out中,待后面的编码器对消息进行编码 out.add(request); } }package com.dingw.bean; import io.netty.handler.codec.http.FullHttpResponse; /** * @Author Dingwei * @Date 2018/1/15 10:14 * @ClassName HttpXmlResponse * @Description 封装一个HttpXml应答对象 */ public class HttpXmlResponse { private FullHttpResponse fullHttpResponse; //业务需要发送的应答POJO对象 private Object result; public HttpXmlResponse(FullHttpResponse fullHttpResponse, Object result) { this.fullHttpResponse = fullHttpResponse; this.result = result; } public HttpXmlResponse() { } @Override public String toString() { return "HttpXmlResponse{" + "fullHttpResponse=" + fullHttpResponse + ", result=" + result + '}'; } public FullHttpResponse getFullHttpResponse() { return fullHttpResponse; } public void setFullHttpResponse(FullHttpResponse fullHttpResponse) { this.fullHttpResponse = fullHttpResponse; } public Object getResult() { return result; } public void setResult(Object result) { this.result = result; } }package com.dingw.bean; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse; import java.util.List; /** * @Author Dingwei * @Date 2018/1/15 10:09 * @ClassName HttpXmlResponseDecoder * @Description 应答消息解码类 */ public class HttpXmlResponseDecoder extends AbstractHttpXmlDecoder<FullHttpResponse> { protected HttpXmlResponseDecoder(Class<?> clazz) { super(clazz,false); } public HttpXmlResponseDecoder(Class<?> clazz,boolean isPrintlong){ super(clazz,isPrintlong); } protected void decode(ChannelHandlerContext ctx, FullHttpResponse msg, List<Object> out) throws Exception { System.out.println("应答消息解码类: 开始解码"); HttpXmlResponse httpXmlResponse = new HttpXmlResponse(msg, decode0(ctx, msg.content())); out.add(httpXmlResponse); System.out.println("应答消息解码类: 解码完成"); } }package com.dingw.bean; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse; import java.util.List; import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH; import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE; import static io.netty.handler.codec.http.HttpResponseStatus.OK; import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; /** * @Author Dingwei * @Date 2018/1/15 10:02 * @ClassName HttpXmlResponseEncoder * @Description 应答消息编码类 */ public class HttpXmlResponseEncoder extends AbstractHttpXmlEncoder<HttpXmlResponse> { protected void encode(ChannelHandlerContext ctx, HttpXmlResponse msg, List<Object> out) throws Exception { ByteBuf body = encode0(ctx, msg.getResult()); FullHttpResponse response = msg.getFullHttpResponse(); if (response == null) { response = new DefaultFullHttpResponse(HTTP_1_1, OK, body); } else { response = new DefaultFullHttpResponse(msg.getFullHttpResponse().protocolVersion(), msg.getFullHttpResponse().status(), body); } response.headers().set(CONTENT_TYPE, "text/xml"); response.headers().setInt(CONTENT_LENGTH, body.readableBytes()); out.add(response); System.out.println("应答消息编码类 编码完成"); } }package com.dingw.bean; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.codec.http.HttpResponseEncoder; import java.net.InetSocketAddress; /** * @Author Dingwei * @Date 2018/1/15 9:59 * @ClassName HttpXmlServer * @Description */ public class HttpXmlServer { public void run(final int port) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast("http-decoder", new HttpRequestDecoder()); ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(65536)); ch.pipeline().addLast("xml-decoder", new HttpXmlRequestDecoder(Order.class, true)); ch.pipeline().addLast("http-encoder", new HttpResponseEncoder()); ch.pipeline().addLast("xml-encoder", new HttpXmlResponseEncoder()); ch.pipeline().addLast("xmlServerHandler", (ChannelHandler) new HttpXmlServerHandler()); } }); ChannelFuture future = b.bind(new InetSocketAddress(port)).sync(); System.out.println("HTTP订购服务器启动,网址是 : " + "http://localhost:" + port); future.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = 8080; if (args.length > 0) { try { port = Integer.parseInt(args[0]); } catch (NumberFormatException e) { e.printStackTrace(); } } new HttpXmlServer().run(port); } }