netty 实现tomcat的示例代码

2023-12-02 0 476
目录
  • netty 实现tomcat
    • 自定义基础类
    • netty 服务端
    • 使用测试

netty 实现tomcat

自定义基础类

TomcatServlet

public abstract class TomcatServlet {

public void service(ServletRequest request, ServletResponse response){
if (\”GET\”.equalsIgnoreCase(request.getMethod())){
doGet(request, response);
}else if (\”POST\”.equalsIgnoreCase(request.getMethod())){
doPost(request, response);
}else {
doResponse(response, \”暂不支持其它请求方法\”);
}
}

public abstract void doGet(ServletRequest request, ServletResponse response);
public abstract void doPost(ServletRequest request, ServletResponse response);

public void doResponse(ServletResponse response, String message){
response.write(message);
}
}

ServletRequest

@Data
public class ServletRequest {

private ChannelHandlerContext context;
private HttpRequest httpRequest;

public ServletRequest(){

}

public ServletRequest(ChannelHandlerContext context, HttpRequest httpRequest){
this.context = context;
this.httpRequest = httpRequest;
}

public String getMethod(){
return httpRequest.method().name();
}

public HttpHeaders getHeaders(){
return httpRequest.headers();
}

public Map<String, List<String>> getParameters(){
QueryStringDecoder decoder = new QueryStringDecoder(httpRequest.uri());
return decoder.parameters();
}

public Map<String,String> getPostFormParameters(){
Map<String,String> params = new HashMap<>();

HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(httpRequest);
decoder.getBodyHttpDatas().forEach(item -> {
if (item.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute){
Attribute attribute = (Attribute) item;

try {
String key = attribute.getName();
String value = attribute.getValue();

params.put(key, value);
}catch (Exception e){
e.printStackTrace();
}
}
});

return params;
}

public Map<String, Object> getPostBody(){
ByteBuf content = ((FullHttpRequest)httpRequest).content();
byte[] bytes = new byte[content.readableBytes()];
content.readBytes(bytes);

return JSON.parseObject(new String(bytes)).getInnerMap();
}
}

ServletResponse

@Data
public class ServletResponse {

private ChannelHandlerContext context;
private HttpRequest httpRequest;

public ServletResponse(){

}

public ServletResponse(ChannelHandlerContext context, HttpRequest httpRequest){
this.context = context;
this.httpRequest = httpRequest;
}

public void write(String message){
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
response.headers().set(\”Content-Type\”,\”application/json;charset=utf-8\”);
response.content().writeCharSequence(message, StandardCharsets.UTF_8);

context.channel().writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
}
}

CustomServlet

ublic class CustomServlet extends TomcatServlet{

@Override
public void doGet(ServletRequest request, ServletResponse response) {
System.out.println(\”处理GET请求\”);
System.out.println(\”请求参数为:\”);
request.getParameters().forEach((key,value) -> System.out.println(key + \” ==> \”+value));

doResponse(response, \”GET success\”);
}

@Override
public void doPost(ServletRequest request, ServletResponse response) {
if (request.getHeaders().get(\”Content-Type\”).contains(\”x-www-form-urlencoded\”)){
System.out.println(\”处理POST Form请求\”);
System.out.println(\”请求参数为:\”);
request.getPostFormParameters().forEach((key,value) -> System.out.println(key + \” ==> \” + value));

doResponse(response, \”POST Form success\”);
}else if (request.getHeaders().get(\”Content-Type\”).contains(\”application/json\”)){
System.out.println(\”处理POST json请求\”);
System.out.println(\”请求参数为:\”);
request.getPostBody().forEach((key,value) -> System.out.println(key + \” ==> \” + value));

doResponse(response, \”POST json success\”);
}else {
doResponse(response, \”error:暂不支持其它post请求方式\”);
}
}
}

ServletMapping:url与对应的TomcatServlet映射

public class ServletMapping {

private static final Map<String,TomcatServlet> urlServletMapping = new HashMap<>();

public static Map<String, TomcatServlet> getUrlServletMapping(){
return urlServletMapping;
}
}

web.properties:使用properties存储url与对应的TomcatServet

servlet.url=/hello
servlet.className=com.example.demo.tomcat.servlet.CustomServlet

netty 服务端

CustomServerHandler

public class CustomServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, FullHttpRequest request) throws Exception {
String uri = request.uri();
String path = uri;
if (uri.contains(\”?\”)){
path = uri.substring(0,uri.indexOf(\”?\”));
}

if (ServletMapping.getUrlServletMapping().containsKey(path)){
ServletRequest servletRequest = new ServletRequest(channelHandlerContext, request);
ServletResponse servletResponse = new ServletResponse(channelHandlerContext, request);

ServletMapping.getUrlServletMapping().get(path).service(servletRequest, servletResponse);
}else {
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
response.content().writeCharSequence(\”404 NOT FOUND:\”+path+\”不存在\”, StandardCharsets.UTF_8);

channelHandlerContext.channel().writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
}
}
}

NettyServer

public class NettyServer {

private static final Properties webProperties = new Properties();

public static void init(){
try {
InputStream inputStream = new FileInputStream(\”./web.properties\”);
webProperties.load(inputStream);

for (Object item : webProperties.keySet()){
String key = (String)item;
if (key.endsWith(\”.url\”)){
String servletKey = key.replaceAll(\”\\\\.url\”,\”\\\\.className\”);
String servletName = webProperties.getProperty(servletKey);

TomcatServlet servlet = (TomcatServlet) Class.forName(servletName).newInstance();
ServletMapping.getUrlServletMapping().put(webProperties.getProperty(key),servlet);
}
}
}catch (Exception e){
e.printStackTrace();
}
}

public static void startServer(int port){
init();

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<SocketChannel>() {

@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 CustomServerHandler());
}
});

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

netty 实现tomcat的示例代码

处理GET请求请求参数为:name ==> [瓜田李下]age ==> [20]

get请求:localhost:8000/hello2?name=瓜田李下&age=20

netty 实现tomcat的示例代码

/hello2路径没有对应的TomcatServlet处理

Post form请求:x-www-form-urlencoded

netty 实现tomcat的示例代码

处理POST Form请求请求参数为:name ==> 瓜田李下age ==> 20

Post json请求

netty 实现tomcat的示例代码

处理POST json请求请求参数为:name ==> 瓜田李下age ==> 20

Post form-data请求

netty 实现tomcat的示例代码

目前只支持x-www-form-urlencoded、post json请求,不支持其它请求方式

Put:localhost:8000/hello?name=瓜田李下&age=20

netty 实现tomcat的示例代码

目前只支持GET、POST请求方法,不支持其它方法

到此这篇关于netty 实现tomcat的文章就介绍到这了,更多相关netty 实现tomcat内容请搜索悠久资源以前的文章或继续浏览下面的相关文章希望大家以后多多支持悠久资源!

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悠久资源 Tomcat netty 实现tomcat的示例代码 https://www.u-9.cn/server/tomcat/32544.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务