FullHttpRequest
public interface FullHttpRequest extends HttpRequest, FullHttpMessage {
FullHttpRequest duplicate();
FullHttpRequest retainedDuplicate();
FullHttpRequest copy();
FullHttpRequest replace(ByteBuf var1);
FullHttpRequest retain();
FullHttpRequest retain(int var1);
FullHttpRequest touch();
FullHttpRequest touch(Object var1);
FullHttpRequest setUri(String var1);
FullHttpRequest setMethod(HttpMethod var1);
FullHttpRequest setProtocolVersion(HttpVersion var1);
}
HttpRequest
public interface HttpRequest extends HttpMessage {
HttpMethod method();
HttpRequest setMethod(HttpMethod var1);
String uri();
HttpRequest setUri(String var1);
HttpRequest setProtocolVersion(HttpVersion var1);
}
DefaultFullHttpRequest
public class DefaultFullHttpRequest extends DefaultHttpRequest implements FullHttpRequest {
private final ByteBuf content;
private final HttpHeaders trailingHeader;
private int hash;
public DefaultFullHttpRequest(HttpVersion httpVersion, HttpMethod method, String uri) {
public DefaultFullHttpRequest(HttpVersion httpVersion, HttpMethod method, String uri, ByteBuf content) {
public DefaultFullHttpRequest(HttpVersion httpVersion, HttpMethod method, String uri, boolean validateHeaders) {
public DefaultFullHttpRequest(HttpVersion httpVersion, HttpMethod method, String uri, ByteBuf content, boolean validateHeaders) {
public DefaultFullHttpRequest(HttpVersion httpVersion, HttpMethod method, String uri, ByteBuf content, HttpHeaders headers, HttpHeaders trailingHeader) {
super(httpVersion, method, uri, headers);
this.content = (ByteBuf)ObjectUtil.checkNotNull(content, "content");
this.trailingHeader = (HttpHeaders)ObjectUtil.checkNotNull(trailingHeader, "trailingHeader");
}
public HttpHeaders trailingHeaders() {
public ByteBuf content() {
public int refCnt() {
public FullHttpRequest retain() {
public FullHttpRequest retain(int increment) {
public FullHttpRequest touch() {
public FullHttpRequest touch(Object hint) {
public boolean release() {
public boolean release(int decrement) {
public FullHttpRequest setUri(String uri) {
public FullHttpRequest setMethod(HttpMethod method) {
public FullHttpRequest setProtocolVersion(HttpVersion version) {
public FullHttpRequest duplicate() {
public FullHttpRequest retainedDuplicate() {
public FullHttpRequest copy() {
public FullHttpRequest replace(ByteBuf content) {
public int hashCode() {
public boolean equals(Object o) {
public String toString() {
FullHttpResponse
public interface FullHttpResponse extends HttpResponse, FullHttpMessage {
FullHttpResponse duplicate();
FullHttpResponse retainedDuplicate();
FullHttpResponse copy();
FullHttpResponse replace(ByteBuf var1);
FullHttpResponse retain();
FullHttpResponse retain(int var1);
FullHttpResponse touch();
FullHttpResponse touch(Object var1);
FullHttpResponse setProtocolVersion(HttpVersion var1);
FullHttpResponse setStatus(HttpResponseStatus var1);
}
HttpResponse
public interface HttpResponse extends HttpMessage {
HttpResponseStatus status();
HttpResponse setStatus(HttpResponseStatus var1);
HttpResponse setProtocolVersion(HttpVersion var1);
}
DefaultFullHttpResponse
public class DefaultFullHttpResponse extends DefaultHttpResponse implements FullHttpResponse {
private final ByteBuf content;
private final HttpHeaders trailingHeaders;
private int hash;
public DefaultFullHttpResponse(HttpVersion version, HttpResponseStatus status) {
public DefaultFullHttpResponse(HttpVersion version, HttpResponseStatus status, ByteBuf content) {
public DefaultFullHttpResponse(HttpVersion version, HttpResponseStatus status, boolean validateHeaders) {
public DefaultFullHttpResponse(HttpVersion version, HttpResponseStatus status, boolean validateHeaders, boolean singleFieldHeaders) {
public DefaultFullHttpResponse(HttpVersion version, HttpResponseStatus status, ByteBuf content, boolean validateHeaders) {
public DefaultFullHttpResponse(HttpVersion version, HttpResponseStatus status, ByteBuf content, boolean validateHeaders, boolean singleFieldHeaders) {
public DefaultFullHttpResponse(HttpVersion version, HttpResponseStatus status, ByteBuf content, HttpHeaders headers, HttpHeaders trailingHeaders) {
super(version, status, headers);
this.content = (ByteBuf)ObjectUtil.checkNotNull(content, "content");
this.trailingHeaders = (HttpHeaders)ObjectUtil.checkNotNull(trailingHeaders, "trailingHeaders");
}
public HttpHeaders trailingHeaders() {
public ByteBuf content() {
public int refCnt() {
public FullHttpResponse retain() {
public FullHttpResponse retain(int increment) {
public FullHttpResponse touch() {
public FullHttpResponse touch(Object hint) {
public boolean release() {
public boolean release(int decrement) {
public FullHttpResponse setProtocolVersion(HttpVersion version) {
public FullHttpResponse setStatus(HttpResponseStatus status) {
public FullHttpResponse duplicate() {
public FullHttpResponse retainedDuplicate() {
public FullHttpResponse copy() {
public FullHttpResponse replace(ByteBuf content) {
public int hashCode() { public boolean equals(Object o) {
public String toString() {
HttpMessage
public interface HttpMessage extends HttpObject {
HttpVersion protocolVersion();
HttpMessage setProtocolVersion(HttpVersion var1);
HttpHeaders headers();
}
HttpObject
public interface HttpObject extends DecoderResultProvider {
/** @deprecated */
@Deprecated
DecoderResult getDecoderResult();
}
DecoderResultProvider
public interface DecoderResultProvider {
DecoderResult decoderResult();
void setDecoderResult(DecoderResult var1);
}
QueryStringDecoder
public class QueryStringDecoder {
private static final int DEFAULT_MAX_PARAMS = 1024;
private final Charset charset;
private final String uri;
private final int maxParams;
private final boolean semicolonIsNormalChar;
private int pathEndIdx;
private String path;
private Map> params;
public QueryStringDecoder(String uri) {
public QueryStringDecoder(String uri, boolean hasPath) {
public QueryStringDecoder(String uri, Charset charset) {
public QueryStringDecoder(String uri, Charset charset, boolean hasPath) {
public QueryStringDecoder(String uri, Charset charset, boolean hasPath, int maxParams) {
public QueryStringDecoder(String uri, Charset charset, boolean hasPath, int maxParams, boolean semicolonIsNormalChar) {
public QueryStringDecoder(URI uri) {
public QueryStringDecoder(URI uri, Charset charset) {
public QueryStringDecoder(URI uri, Charset charset, int maxParams) {
public QueryStringDecoder(URI uri, Charset charset, int maxParams, boolean semicolonIsNormalChar) {
public String uri() {
public String path() {
public String rawPath() {
public String rawQuery() {
public Map> parameters() {
public static String decodeComponent(String s) {
public static String decodeComponent(String s, Charset charset) {
public String toString() {
private int pathEndIdx() {
private static int findPathEndIndex(String uri) {
private static String decodeComponent(String s, int from, int toExcluded, Charset charset, boolean isPath) {
private static boolean addParam(String s, int nameStart, int valueStart, int valueEnd, Map> params, Charset charset) {
private static Map> decodeParams(String s, int from, Charset charset, int paramsLimit, boolean semicolonIsNormalChar) {
HttpPostRequestDecoder
public class HttpPostRequestDecoder implements InterfaceHttpPostRequestDecoder {
static final int DEFAULT_DISCARD_THRESHOLD = 10485760;
private final InterfaceHttpPostRequestDecoder decoder;
public HttpPostRequestDecoder(HttpRequest request) {
public HttpPostRequestDecoder(HttpDataFactory factory, HttpRequest request) {
public HttpPostRequestDecoder(HttpDataFactory factory, HttpRequest request, Charset charset) {
public static boolean isMultipart(HttpRequest request) {
public boolean isMultipart() {
public void setDiscardThreshold(int discardThreshold) {
public int getDiscardThreshold() {
public List getBodyHttpDatas() {
public List getBodyHttpDatas(String name) {
public InterfaceHttpData getBodyHttpData(String name) {
public InterfaceHttpPostRequestDecoder offer(HttpContent content) {
public boolean hasNext() {
public InterfaceHttpData next() {
public InterfaceHttpData currentPartialHttpData() {
public void destroy() {
public void cleanFiles() {
public void removeHttpDataFromClean(InterfaceHttpData data) {
protected static String[] getMultipartDataBoundary(String contentType) {
private static String[] splitHeaderContentType(String sb) {
*******
内部类:HttpPostRequestDecoder.ErrorDataDecoderException
public static class ErrorDataDecoderException extends DecoderException {
private static final long serialVersionUID = 5020247425493164465L;
public ErrorDataDecoderException() {
public ErrorDataDecoderException(String msg) {
public ErrorDataDecoderException(Throwable cause) {
public ErrorDataDecoderException(String msg, Throwable cause) {
*******
内部类:HttpPostRequestDecoder.EndOfDataDecoderException
public static class EndOfDataDecoderException extends DecoderException {
private static final long serialVersionUID = 1336267941020800769L;
public EndOfDataDecoderException() {
*******
内部类:HttpPostRequestDecoder.NotEnoughDataDecoderException
public static class NotEnoughDataDecoderException extends DecoderException {
private static final long serialVersionUID = -7846841864603865638L;
public NotEnoughDataDecoderException() {
public NotEnoughDataDecoderException(String msg) {
public NotEnoughDataDecoderException(Throwable cause) {
public NotEnoughDataDecoderException(String msg, Throwable cause) {
*******
内部枚举:MultiPartStatus
protected static enum MultiPartStatus {
NOTSTARTED,
PREAMBLE,
HEADERDELIMITER,
DISPOSITION,
FIELD,
FILEUPLOAD,
MIXEDPREAMBLE,
MIXEDDELIMITER,
MIXEDDISPOSITION,
MIXEDFILEUPLOAD,
MIXEDCLOSEDELIMITER,
CLOSEDELIMITER,
PREEPILOGUE,
EPILOGUE;
private MultiPartStatus() {
}
}
}
HttpResponseEncoder
public class HttpResponseEncoder extends HttpObjectEncoder {
public HttpResponseEncoder() {
public boolean acceptOutboundMessage(Object msg) throws Exception {
protected void encodeInitialLine(ByteBuf buf, HttpResponse response) throws Exception {
protected void sanitizeHeadersBeforeEncode(HttpResponse msg, boolean isAlwaysEmpty) {
protected boolean isContentAlwaysEmpty(HttpResponse msg) {
**********
服务端
CustomHttpHandler
public class CustomHttpHandler extends SimpleChannelInboundHandler {
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, FullHttpRequest fullHttpRequest) throws Exception {
switch (fullHttpRequest.method().name()){
case "GET": processGetRequest(fullHttpRequest); break;
case "POST": {
if (fullHttpRequest.headers().get("Content-Type").contains("x-www-form-urlencoded")){
processPostFormRequest(fullHttpRequest);
}else if (fullHttpRequest.headers().get("Content-Type").contains("application/json")){
processPostJsonRequest(fullHttpRequest);
}
}
}
ByteBuf buf = PooledByteBufAllocator.DEFAULT.buffer();
buf.writeCharSequence("success", StandardCharsets.UTF_8);
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf);
response.headers().set("Content-Type","application/json;charset=UTF-8");
response.headers().set("Content-Length",response.content().readableBytes());
channelHandlerContext.channel().writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
}
private void processGetRequest(FullHttpRequest request){
System.out.println("处理get请求");
QueryStringDecoder decoder = new QueryStringDecoder(request.uri());
Map> params = decoder.parameters();
params.forEach((key, value) -> System.out.println(key + " ==> "+ value));
}
private void processPostFormRequest(FullHttpRequest request){
System.out.println("处理post form请求");
HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(request);
List httpDataList = decoder.getBodyHttpDatas();
httpDataList.forEach(item -> {
if (item.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute){
Attribute attribute = (Attribute) item;
try {
System.out.println(attribute.getName() + " ==> " + attribute.getValue());
}catch (Exception e){
e.printStackTrace();
}
}
});
}
private void processPostJsonRequest(FullHttpRequest request){
System.out.println("处理post json请求");
ByteBuf content = request.content();
byte[] bytes = new byte[content.readableBytes()];
content.readBytes(bytes);
JSONObject jsonObject = JSONObject.parseObject(new String(bytes));
jsonObject.getInnerMap().forEach((key,value) -> System.out.println(key + " ==> " + value));
}
}
NettyServer
public class NettyServer {
public static void startServer(int port){
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childHandler(new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline channelPipeline = socketChannel.pipeline();
channelPipeline.addLast(new HttpRequestDecoder());
channelPipeline.addLast(new HttpResponseEncoder());
channelPipeline.addLast(new HttpObjectAggregator(65535));
channelPipeline.addLast(new CustomHttpHandler());
}
});
ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
channelFuture.channel().closeFuture().sync();
}catch (Exception e){
e.printStackTrace();
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
public static void main(String[] args) {
startServer(8000);
}
}
**********
使用测试
get 请求:localhost:8000/hello?name=瓜田李下&age=20
15:20:42.090 [nioEventLoopGroup-3-2] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkBounds: true
15:20:42.091 [nioEventLoopGroup-3-2] DEBUG io.netty.util.ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@236a9fe3
15:20:42.124 [nioEventLoopGroup-3-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.maxCapacityPerThread: 4096
15:20:42.126 [nioEventLoopGroup-3-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.ratio: 8
15:20:42.126 [nioEventLoopGroup-3-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.chunkSize: 32
15:20:42.126 [nioEventLoopGroup-3-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.blocking: false
处理get请求
name ==> [瓜田李下]
age ==> [20]
post form请求
15:33:25.270 [nioEventLoopGroup-3-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkBounds: true
15:33:25.271 [nioEventLoopGroup-3-1] DEBUG io.netty.util.ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@2e03ba32
15:33:25.307 [nioEventLoopGroup-3-2] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.maxCapacityPerThread: 4096
15:33:25.309 [nioEventLoopGroup-3-2] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.ratio: 8
15:33:25.309 [nioEventLoopGroup-3-2] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.chunkSize: 32
15:33:25.309 [nioEventLoopGroup-3-2] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.blocking: false
处理post form请求
name ==> 瓜田李下
age ==> 20
post json请求
15:35:44.038 [nioEventLoopGroup-3-2] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkBounds: true
15:35:44.039 [nioEventLoopGroup-3-2] DEBUG io.netty.util.ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@400ded19
15:35:44.072 [nioEventLoopGroup-3-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.maxCapacityPerThread: 4096
15:35:44.074 [nioEventLoopGroup-3-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.ratio: 8
15:35:44.074 [nioEventLoopGroup-3-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.chunkSize: 32
15:35:44.074 [nioEventLoopGroup-3-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.blocking: false
处理post json请求
name ==> 瓜田李下
age ==> 20