directory
Netty application scenarios
Netty implementation file upload and download
Third, the program demonstration
1. Download the demo
2. Upload the demo
Netty application scenarios
Having talked about some of Netty’s components, let’s talk about what we care most about. What can it do? After all, we study for use. I can simply summarize, all involved in the network, can use Neety to achieve!
- Build various Java middleware with high performance and low latency, such as MQ, distributed service framework, ESB message bus, etc. Netty is mainly used as a basic communication framework to provide high performance and low latency communication services.
- The basic communication framework of public or private protocol stack, for example, the asynchronous and high-performance WebSocket protocol stack can be built based on Netty;
- For applications in various fields, such as big data and games, Netty is used as a high-performance communication framework for data distribution, transmission, and summary of internal modules to achieve high-performance communication between modules.
The next few articles will focus on the implementation of Netty.
Netty implementation file upload and download
1, MultipartRequest
import io.netty.handler.codec.http.multipart.FileUpload; import org.json.simple.JSONObject; import java.util.Map; ** @author DarkKing */ public class MultipartRequest {private Map<String, FileUpload> fileUploads; private JSONObject params; public Map<String, FileUpload> getFileUploads() { return fileUploads; } public void setFileUploads(Map<String, FileUpload> fileUploads) { this.fileUploads = fileUploads; } public JSONObject getParams() { return params; } public void setParams(JSONObject params) { this.params = params; }}Copy the code
Defines an HTTP wrapped object. Save the corresponding transmission parameters.
2, FileServer
import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import java.net.InetSocketAddress; */ Public class FileServer {private final int port; public FileServer(int port) { this.port = port; } public static void main(String[] args) throws InterruptedException { int port = 9999; FileServer fileServer = new FileServer(port); System.out.println(" Server is about to start "); fileServer.start(); System.out.println(" Server down "); } public void start() throws InterruptedException { final FileServerHandle serverHandler = new FileServerHandle(); /* Thread group */ EventLoopGroup group = new NioEventLoopGroup(); Pipeline pipeline = new Pipeline(); */ ServerBootstrap b = new ServerBootstrap(); B.g roup (group) * /. / * thread group into the channel (NioServerSocketChannel. Class) / * specified using NIO network transmission * /. LocalAddress (new InetSocketAddress(port))/* Specifies the port on which the server is listening */ /* Every time the server receives a connection request, it initiates a new socket communication, i.e. channel, So this code adds handle*/.childHandler(pipeline) to this subchannel; ChannelFuture f = b.bind().sync(); /* Asynchronously bind to the server, sync() will block until complete */ system.out.println ("Netty server start,port is "+ port); f.channel().closeFuture().sync(); Override () {override (channel) {override (channel) {override (channel) {override (channel) {override (channel); /* Close thread group gracefully */}}}Copy the code
Use Netty to realize the file server.
3, Pipeline
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.codec.http.HttpResponseEncoder; import io.netty.util.concurrent.DefaultEventExecutorGroup; import io.netty.util.concurrent.EventExecutorGroup; /** * By: DarkKIng * Created date: 2019/12/17 * Responsibility chain */ public class Pipeline extends ChannelInitializer<SocketChannel> {private EventorGroup businessEventExecutorGroup = new DefaultEventExecutorGroup(10); @Override protected void initChannel(SocketChannel ch) { ChannelPipeline pipeline = ch.pipeline(); HttpResponseEncoder(HttpResponseEncoder()); /** * HttpResponseEncoder(); /** */ HttpRequestDecoder(); /** */ HttpRequestDecoder(); /** * merge request */ pipeline.addlast (" Aggregator ", new HttpObjectAggregator(655300000)); / * * * normal business logic to handle * / pipeline in addLast (businessEventExecutorGroup, new FileServerHandle ()); }}Copy the code
Compile responsibility chain, request will be pushed from top to bottom through the codec, request and receive HTTPObject, and finally execute the business class FileServerHandle.
4, FileServerHandle
import io.netty.buffer.Unpooled; import io.netty.channel.*; import io.netty.channel.ChannelHandler.Sharable; import io.netty.handler.codec.http.*; import io.netty.handler.codec.http.multipart.*; import io.netty.util.CharsetUtil; import org.json.simple.JSONObject; import java.io.*; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; /** * By: DarkKIng * Created date: 2019/12/17 Download file handler * / @ Sharable public class FileServerHandle extends SimpleChannelInboundHandler < FullHttpRequest > { /* After the client reads the data, Override protected void channelRead0(ChannelHandlerContext CTX, FullHttpRequest Request) throws Exception {// Print the request URL System.out.println(request.uri()); If (request.uri().equals("/downFile")) {responseExportFile(CTX, "D://model.txt", "model.txt"); } if (request.uri().equals("/upLoadFile")) {MultipartRequest MultipartBody = getMultipartBody(request); Map<String, FileUpload> fileUploads = MultipartBody.getFileUploads(); For (String key: fileuploads.keyset ()) {// Get the file object FileUpload file = fileuploads.get (key); System.out.println("fileName is" + file.getFile().getPath()); InputStream in = new FileInputStream(file.getFile()); BufferedReader bf = new BufferedReader(new InputStreamReader(in)); String content = bf.lines().collect(Collectors.joining("\n")); // Print system.out. println("content is \n" + content); } JSONObject params = multipartBody.getParams (); System.out.println(jsonObject.tojsonString (params)); }} /* Override public void channelActive(ChannelHandlerContext CTX) throws Exception { ctx.writeAndFlush(Unpooled.copiedBuffer( "Hello Netty", CharsetUtil.UTF_8)); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } /** * <p> ** @param CTX * @author DarkKing 2019-12-17 */ public static void responseExportFile(ChannelHandlerContext ctx, String path, String name) { File file = new File(path); Final RandomAccessFile raf = new RandomAccessFile(file, "r"); long fileLength = raf.length(); HttpResponse response = new DefaultHttpResponse(httpversion.http_1_1, httpresponseStatus.ok); // Set response.headers().set(httpHeadernames.content_length, fileLength); response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/octet-stream; charset=UTF-8"); response.headers().add(HttpHeaderNames.CONTENT_DISPOSITION, "attachment; filename="" + URLEncoder.encode(file.getName(), "UTF-8") + "";" ); ctx.write(response); SendFileFuture = ctx. write(new DefaultFileRegion(raf.getChannel(), 0, fileLength), ctx.newProgressivePromise()); SendFileFuture. AddListener (new ChannelProgressiveFutureListener () {/ / file transfer completed, listener @ Override public void operationComplete(ChannelProgressiveFuture future) throws Exception { System.out.println("file {} transfer complete."); } @override public void operationFile (ChannelProgressiveFuture Future, long Progress, long total) throws Exception { if (total < 0) { System.out.println("file {} transfer progress: {}"); } else { System.out.println("file {} transfer progress: {}/{}"); }}}); WriteAndFlush (lasthttPContent.empty_last_Content); // Flush buffer data with end of file identifier ctx.writeAndFlush(lasthttPContent.empty_last_Content); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); @author DarkKing 2019/10/9 15:24 * @params [CTX, HttpDecode] */ private static MultipartRequest getMultipartBody(FullHttpRequest Request) {try {// Create HTTP object factory HttpDataFactory factory = new DefaultHttpDataFactory(true); HttpPostRequestDecoder = new HttpPostRequestDecoder(factory, request); httpDecoder.setDiscardThreshold(0); if (httpDecoder ! Final HttpContent chunk = (HttpContent) request; // Load the object into the adder. httpDecoder.offer(chunk); If (chunk instanceof LastHttpContent) {// Custom object bean MultipartRequest MultipartRequest = new MultipartRequest(); Map<String, FileUpload> fileUploads = new HashMap<>(); JSONObject body = new JSONObject(); / / by the iterator for the content of the HTTP Java. Util. List < InterfaceHttpData > InterfaceHttpDataList = httpDecoder. GetBodyHttpDatas (); For (InterfaceHttpData data: InterfaceHttpDataList) {// If the data type is a file type, save it to the fileUploads object if (data! = null && InterfaceHttpData.HttpDataType.FileUpload.equals(data.getHttpDataType())) { FileUpload fileUpload = (FileUpload) data; fileUploads.put(data.getName(), fileUpload); } // If the data type is parameter type, Object is saved to the body of the if (data. GetHttpDataType () = = InterfaceHttpData. HttpDataType. Attribute) {Attribute Attribute = (Attribute) data; body.put(attribute.getName(), attribute.getValue()); }} / / storage file information multipartRequest. SetFileUploads (fileUploads); / / store parameter information multipartRequest. SetParams (body); return multipartRequest; } } } catch (IOException e) { e.printStackTrace(); } return null; }}Copy the code
Business execution class, the realization of the file upload and download interface. If the request is downFile, the file is downloaded. If the request is upLoadFile, the file is uploaded
Third, the program demonstration
1. Download the demo
Start the server
The browser downloads the file and correctly downloads it to the test.txt file
2. Upload the demo
Use apiPost or Postman to upload files
The file is uploaded and read successfully. Procedure
This blog post demonstrates how to implement your own file upload and download service using Netty without using Spring or Tomcat as a server. And according to the request to achieve the corresponding API interface operation. Of course, if you want to use Netty to encapsulate your API as easily and formally as Spring, then you need to encapsulate your own implementation. Interested friends can try their own
\