栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Netty基于Http协议的服务端入门开发,2021年Java笔试题总

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Netty基于Http协议的服务端入门开发,2021年Java笔试题总

public void run(final int port, final String url) throws Exception {

EventLoopGroup bossGroup = new NioEventLoopGroup();

EventLoopGroup workerGroup = new Ni

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

oEventLoopGroup();

try {

ServerBootstrap b = new ServerBootstrap();

b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)

.childHandler(new ChannelInitializer() {

@Override

protected void initChannel(SocketChannel ch) throws Exception {

// 添加请求消息解码器

ch.pipeline().addLast(“http-decoder”, new HttpRequestDecoder());

//HttpObjectAggregator的作用 将多个消息转换为单一的FullHttpRequest或者FullHttpResponse

ch.pipeline().addLast(“http-aggregator”, new HttpObjectAggregator(65536));

// 添加响应解码器

ch.pipeline().addLast(“http-encoder”, new HttpResponseEncoder());

// 支持异步发送大的码流(大的文件传输),但不占用过多的内存,防止java内存溢出

ch.pipeline().addLast(“http-chunked”, new ChunkedWriteHandler());

// 添加自定义handler 处理文件服务器业务逻辑

ch.pipeline().addLast(“fileServerHandler”, new HttpFileServerHandler(url));

}

});

ChannelFuture future = b.bind(“127.0.0.1”, port).sync();

System.out.println("HTTP文件目录服务器启动,网址是 : " + “http://127.0.0.1:” + port + url);

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();

}

}

String url = DEFAULT_URL;

if (args.length > 1)

url = args[1];

new HttpFileServer().run(port, url);

}

}

HttpFileServerHandler


package com.dpb.netty.http;

import static io.netty.handler.codec.http.HttpHeaders.isKeepAlive;

import static io.netty.handler.codec.http.HttpHeaders.setContentLength;

import static io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION;

import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;

import static io.netty.handler.codec.http.HttpHeaders.Names.LOCATION;

import static io.netty.handler.codec.http.HttpMethod.GET;

import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;

import static io.netty.handler.codec.http.HttpResponseStatus.FORBIDDEN;

import static io.netty.handler.codec.http.HttpResponseStatus.FOUND;

import static io.netty.handler.codec.http.HttpResponseStatus.INTERNAL_SERVER_ERROR;

import static io.netty.handler.codec.http.HttpResponseStatus.METHOD_NOT_ALLOWED;

import static io.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND;

import static io.netty.handler.codec.http.HttpResponseStatus.OK;

import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.RandomAccessFile;

import java.io.UnsupportedEncodingException;

import java.net.URLDecoder;

import java.util.regex.Pattern;

import javax.activation.MimetypesFileTypeMap;

import io.netty.buffer.ByteBuf;

import io.netty.buffer.Unpooled;

import io.netty.channel.ChannelFuture;

import io.netty.channel.ChannelFutureListener;

import io.netty.channel.ChannelHandlerContext;

import io.netty.channel.ChannelProgressiveFuture;

import io.netty.channel.ChannelProgressiveFutureListener;

import io.netty.channel.SimpleChannelInboundHandler;

import io.netty.handler.codec.http.DefaultFullHttpResponse;

import io.netty.handler.codec.http.DefaultHttpResponse;

import io.netty.handler.codec.http.FullHttpRequest;

import io.netty.handler.codec.http.FullHttpResponse;

import io.netty.handler.codec.http.HttpHeaders;

import io.netty.handler.codec.http.HttpResponse;

import io.netty.handler.codec.http.HttpResponseStatus;

import io.netty.handler.codec.http.LastHttpContent;

import io.netty.handler.stream.ChunkedFile;

import io.netty.util.CharsetUtil;

public class HttpFileServerHandler extends SimpleChannelInboundHandler {

private final String url;

public HttpFileServerHandler(String url) {

this.url = url;

}

@Override

public void messageReceived(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {

// 解码失败 400

if (!request.getDecoderResult().isSuccess()) {

sendError(ctx, BAD_REQUEST);

return;

}

// 只支持get方法

if (request.getMethod() != GET) {

sendError(ctx, METHOD_NOT_ALLOWED);

return;

}

//

final String uri = request.getUri();

// 处理Uri地址

final String path = sanitizeUri(uri);

if (path == null) {

sendError(ctx, FORBIDDEN);

return;

}

File file = new File(path);

// 如果文件不存在,或不可访问

if (file.isHidden() || !file.exists()) {

sendError(ctx, NOT_FOUND);

return;

}

// 如果请求是文件夹

if (file.isDirectory()) {

// 请求以 '/'结尾,列出该文件夹下的所有内容

if (uri.endsWith("/")) {

sendListing(ctx, file);

} else {

// 否则自动补全’/’ 然后再重定向访问

sendRedirect(ctx, uri + ‘/’);

}

return;

}

if (!file.isFile()) {

sendError(ctx, FORBIDDEN);

return;

}

RandomAccessFile randomAccessFile = null;

try {

randomAccessFile = new RandomAccessFile(file, “r”);// 以只读的方式打开文件

} catch (FileNotFoundException fnfe) {

sendError(ctx, NOT_FOUND);

return;

}

long fileLength = randomAccessFile.length();

// 创建一个默认的Http响应

HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);

// 设置响应文件大小

setContentLength(response, fileLength);

// 设置 content Type

setContentTypeHeader(response, file);

// 设置 keep alive

if (isKeepAlive(request)) {

response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);

}

ctx.write(response);

ChannelFuture sendFileFuture;

//通过Netty的ChunkedFile对象直接将文件写入发送到缓冲区中

sendFileFuture = ctx.write(new ChunkedFile(randomAccessFile, 0, fileLength, 8192), ctx.newProgressivePromise());

sendFileFuture.addListener(new ChannelProgressiveFutureListener() {

@Override

public void operationProgressed(ChannelProgressiveFuture future, long progress, long total) {

if (total < 0) { // total unknown

System.err.println("Transfer progress: " + progress);

} else {

System.err.println("Transfer progress: " + progress + " / " + total);

}

}

@Override

public void operationComplete(ChannelProgressiveFuture future) throws Exception {

System.out.println(“Transfer complete.”);

}

});

ChannelFuture lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);

//如果不支持keep-Alive,服务器端主动关闭请求

if (!isKeepAlive(request)) {

lastContentFuture.addListener(ChannelFutureListener.CLOSE);

}

}

@Override

public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

cause.printStackTrace();

if (ctx.channel().isActive()) {

sendError(ctx, INTERNAL_SERVER_ERROR);

}

}

private static final Pattern INSECURE_URI = Pattern.compile(".[<>&"].");

private String sanitizeUri(String uri) {

try {

uri = URLDecoder.decode(uri, “UTF-8”);

} catch (UnsupportedEncodingException e) {

try {

uri = URLDecoder.decode(uri, “ISO-8859-1”);

} catch (UnsupportedEncodingException e1) {

throw new Error();

}

}

if (!uri.startsWith(url)) {

return null;

}

if (!uri.startsWith("/")) {

return null;

}

uri = uri.replace(’/’, File.separatorChar);

if (uri.contains(File.separator + ‘.’) || uri.contains(’.’ + File.separator) || uri.startsWith(".")

|| uri.endsWith(".") || INSECURE_URI.matcher(uri).matches()) {

return null;

}

return System.getProperty(“user.dir”) + File.separator + uri;

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/667361.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号