Netty4之如何实现HTTP请求、响应

 更新时间:2023年04月04日 09:51:41   作者:恐龙弟旺仔  
这篇文章主要介绍了Netty4之如何实现HTTP请求、响应问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

前言

我们所编写的项目多以BS为主,用户通过浏览器访问我们的服务器

发送的请求以HTTP请求为主,本例就以Netty4来实现一个接收HTTP请求的服务器,并根据用户请求返回响应

1.Netty中HTTP请求和响应类

请求(FullHttpRequest)

/**
 * Combine the {@link HttpRequest} and {@link FullHttpMessage}, so the request is a <i>complete</i> HTTP
 * request.
 */
public interface FullHttpRequest extends HttpRequest, FullHttpMessage {

可以看到,它结合了HttpRequest、FullHttpMessag,作为一个完整的HTTP请求体。

默认实现为DefaultFullHttpRequest

响应(FullHttpResponse)

/**
 * Combination of a {@link HttpResponse} and {@link FullHttpMessage}.
 * So it represent a <i>complete</i> http response.
 */
public interface FullHttpResponse extends HttpResponse, FullHttpMessage {

同样,它结合了HttpResponse、FullHttpMessage

默认实现为DefaultFullHttpResponse

*

2.Netty中客户端、服务端的编解码器

作为服务端而言:

主要工作就是接收客户端请求,将客户端的请求内容解码;发送响应给客户端,并将发送内容编码

所以,服务端需要两个编解码器

* HttpRequestDecoder(将请求内容解码)

* HttpResponseEncoder(将响应内容编码)

作为客户端而言:

主要工作就是发送请求给服务端,并将发送内容编码;接收服务端响应,并将接收内容解码;

所以,客户端需要两个编解码器

* HttpResponseDecoder(将响应内容解码)

* HttpRequestEncoder(将请求内容编码)

3.Server端编写Handler类处理客户请求

创建Handler,命名为HttpHandler,具体内容如下:

import com.alibaba.fastjson.JSONObject;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
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.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.util.CharsetUtil;
import lombok.Data;

/**
 * 处理HTTP请求
 * @author Administrator
 *
 */
public class HttpHandler extends ChannelInboundHandlerAdapter {

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
	
		if(msg instanceof FullHttpRequest){
			
			FullHttpRequest req = (FullHttpRequest)msg;
			
			try {
				
				// 1.获取URI
				String uri = req.uri();
				
				// 2.获取请求体
				ByteBuf buf = req.content();
				String content = buf.toString(CharsetUtil.UTF_8);
				
				// 3.获取请求方法
				HttpMethod method = req.method();
				
				// 4.获取请求头
				HttpHeaders headers = req.headers();
				
				// 5.根据method,确定不同的逻辑
				if(method.equals(HttpMethod.GET)){
					
					// TODO 
				}
				
				if(method.equals(HttpMethod.POST)){
					// 接收用户输入,并将输入返回给用户
					Content c = new Content();
					c.setUri(uri);
					c.setContent(content);
					
					response(ctx, c);
				}
				
				if(method.equals(HttpMethod.PUT)){
					// TODO 
				}
				
				if(method.equals(HttpMethod.DELETE)){
					// TODO 
				}
			} finally {
				req.release();
			}
		}
	}

	private void response(ChannelHandlerContext ctx, Content c) {

		// 1.设置响应
		FullHttpResponse resp = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
				HttpResponseStatus.OK, 
				Unpooled.copiedBuffer(JSONObject.toJSONString(c), CharsetUtil.UTF_8));
		
		resp.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html; charset=UTF-8");
		
		// 2.发送
		// 注意必须在使用完之后,close channel
		ctx.writeAndFlush(resp).addListener(ChannelFutureListener.CLOSE);
	}
}

@Data
class Content{
	String uri;
	String content;
}

注意:

在处理过程中,把msg转换为FullHttpRequest,可以获取关于请求的所有内容;

在发送响应时必须要监听CLOSE

*

4.测试

启动Server类使用客户端发送请求

在这里,笔者不单独编写Netty客户端代码,直接使用PostMan来充当客户端发送请求,具体如下:

在这里插入图片描述

发送一个post请求,并填写body,点击send,可以看到响应如下所示:

在这里插入图片描述

参考:Netty in Action

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring系统属性及spring.properties配置文件示例详解

    Spring系统属性及spring.properties配置文件示例详解

    spring中有一个SpringProperties类,来保存spring的系统属性,本文结合实例代码对Spring系统属性及spring.properties配置文件相关知识给大家介绍的非常详细,需要的朋友参考下吧
    2023-07-07
  • java中jdk的下载和安装全过程

    java中jdk的下载和安装全过程

    这篇文章主要给大家介绍了关于java中jdk的下载和安装的相关资料,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • java中for循环删除集合陷阱

    java中for循环删除集合陷阱

    java中在增强for循环为什么不能增删集合呢?一个循环迭代,跟集合的增删改没什么关系。修改集合不是for去做的。for只管循环迭代,你在循环里边修改集合,改变集合的长度,顺序对循环都有影响
    2015-05-05
  • java排序高级之选择排序实现方法

    java排序高级之选择排序实现方法

    这篇文章主要介绍了java排序高级之选择排序实现方法,较为全面的分析了选择排序的原理与具体实现技巧,非常具有实用价值,需要的朋友可以参考下
    2015-02-02
  • Java中如何避免sql注入实例详解

    Java中如何避免sql注入实例详解

    SQL注入是最常见的攻击方式之一,它不是利用操作系统或其它系统的漏洞来实现攻击的,而是程序员因为没有做好判断,被不法用户钻了SQL的空子,下面这篇文章主要给大家介绍了关于Java中如何避免sql注入的相关资料,需要的朋友可以参考下
    2022-01-01
  • 详解jenkins自动部署springboot应用的方法

    详解jenkins自动部署springboot应用的方法

    这篇文章主要介绍了详解jenkins自动部署springboot应用的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • SpringBoot项目中application.yml和bootstrap.yml文件的区别及说明

    SpringBoot项目中application.yml和bootstrap.yml文件的区别及说明

    `application.yml`和`bootstrap.yml`都是Spring Boot项目中的配置文件,但它们在加载时机、用途、优先级、配置来源、适用场景和是否必须存在等方面存在区别
    2025-03-03
  • 解析Java和IDEA中的文件打包问题

    解析Java和IDEA中的文件打包问题

    这篇文章主要介绍了Java和IDEA中的文件打包问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-07-07
  • java实现转圈打印矩阵算法

    java实现转圈打印矩阵算法

    这篇文章主要为大家详细介绍了java实现转圈打印矩阵算法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-03-03
  • Java中如何模拟HTTP请求并验证功能

    Java中如何模拟HTTP请求并验证功能

    要模拟HTTP请求并验证功能,你可以使用Spring Boot提供的MockMvc工具,它允许我们在没有实际启动HTTP服务器的情况下测试Spring MVC控制器,下面给大家分享如何模拟HTTP请求并验证功能,感兴趣的朋友一起看看吧
    2024-05-05

最新评论