当前位置:网站首页>A pit in try with resources
A pit in try with resources
2022-06-24 22:10:00 【JAVA Chinese community】
How are you guys , Yesterday, I resumed my previous projects ( About a year ago ), To see this try-catch , And I think of my previous experience of falling into a pit , Made a small demo Let's feel it ~
problem 1
A simple example of downloading a file .
What will happen here ?

@GetMapping("/download")
public void downloadFile(HttpServletResponse response) throws Exception {
String resourcePath = "/java4ye.txt";
URL resource = DemoApplication.class.getResource(resourcePath);
String path = resource.getPath().replace("%20", " ");
try( ServletOutputStream outputStream = response.getOutputStream();
FileInputStream fileInputStream = new FileInputStream(path)) {
byte[] bytes = new byte[8192];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len = 0;
while ((len = fileInputStream.read(bytes)) != -1) {
baos.write(bytes, 0, len);
}
String fileName = "java4ye.txt";
// response.setHeader("content-type", "application/octet-stream;charset=UTF-8");
// response.setContentType("application/octet-stream");
// response.setHeader("Access-Control-Expose-Headers", "File-Name");
// response.setHeader("File-Name", fileName);
// abnormal
int i = 1/0;
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
outputStream.write(baos.toByteArray());
} catch (Exception e) {
throw new DownloadException(e);
}
}
What do you think to choose after reading ?
The exception is captured by the global exception handler and returned to the front end .
The front end cannot be received response Error messages for .

The answer, of course, is 2 La , ha-ha If it is normal, it will not be written

bug memories
During the joint commissioning with the front end , I found that the front end of this exception message did not give a corresponding prompt , I thought it was the front-end problem , Ha ha ha After all, there is nothing wrong with my code .
And the project is separated from the front end and the back end ,response Of content-type and header All of them have been handled , Front end used axios To intercept these responses , There seems to be another one responseType: blob Such things . Then it happens that the front end is not familiar with this thing , He also thought there was something wrong with his front end , however debug When , To see this post Requested response Why is it empty , adopt chrome Browser found .
At this time, I still wonder , Ask him , Are you this Front end intercept Got rid of , Otherwise, I can't see ( I'm so stupid , Now I really want to give myself two slaps to wake up This is nonsense )
Later, I also felt something wrong , Just look at your code carefully , I also asked another colleague to watch it together Guess together ( In the middle of the trip, I got another hole in the front Sin ……)

An hour or two later , I finally got the hang of it , I wonder if it could be this The stream is closed first , That led to this farce ( I was wondering Nine is not separated from ten )
So I try to modify the code , Open try-with-resources , Change to regular try-catch , And in finally Rewrites the closing logic of this flow in , When the program is normal , To close the flow normally , Otherwise don't close .
As a result, the problem was solved smoothly ……
At that time, I thought I was stupid , I didn't think of this for the first time The stream is closed The problem of , And foolishly suspected the browser , Is there a problem with some writing of the front end , Very embarrassed Such a pit ,, I just want to find a hole to drill into ..

See this code again , I think there should be something inside that can be dug out , So there is this article ~ ( Public execution , Take warning )

problem 2
You have seen try-with-resources and try-catch Compiled and decompiled code ? Have you compared their differences ~


The above is given here try-with-resources Module decompiled code , It can be found that there is no... In the decompiled code finally The block .
If you look at the picture above , try-with-resources The function of is the following two points
catch Exception when , Turn off the stream first , Throw an exception again
Add code that normally closes the flow
Did you find this line of code
var15.addSuppressed(var12);
This will lead to Throwable coming

See the function of this method
link :https://blog.csdn.net/qiyan2012/article/details/116173807

It means Hang the exception in the outermost exception , However, you can know from the method comments , This is usually try-with-resources Did it for us secretly .

It's not over here , Please continue to look at it.
problem 3
This anomaly has not yet debug Well , Don't go , Verify the above The closure of the stream Logic
stay OutputStream Of close Method , Finally, it will come to Tomcat Of CoyoteOutputStream in , You can see the flag bit at this time closed and doFlush All are false.

After execution close After the method is closed , This initial from true Turn into false , and closed Also become a true.
meanwhile , This In heap memory buffer HeapByteBuffer There is no time to write new data in , It was shut down directly , The contents are still from my last visit .

After closing the flow , To catch this exception , This is consistent with the code logic we see after decompiling

The following steps are a bit long , Just briefly summarize the key points ~
After the flow is closed , This part of the code is executed as usual .
The exception thrown is SpringMVC Framework of the AbstractHandlerMethodExceptionResolver Capture , And implement doResolveHandlerMethodException To deal with
utilize jackson Of UTF8JsonGenerator To serialize , And use NonClosingOutputStream Yes OutputStream For packaging .
Data write buffer ( Key steps Here's the picture )

You can see that after the flow is closed , here closed Also become true, So the customized information cannot be written to the buffer .
Others in the back flush The operation can't brush out anything .

For example, put it in GitHub Yes …… It is directly put on it together with the examples to be written in the next issue
https://github.com/Java4ye/springboot-demo-4ye

summary
After watching the , You know that I have made a very low-level mistake ( I don't want my face this time , Just dig up some other content and write it together )
Pay attention to the problem of flow closing
Use caution try-with-resources , Consider exceptions , Can this flow be closed .
At the same time, I know try-with-resources Some technical details of , Will not generate finally modular ( My previous mistakes ), Instead, it will help us close the flow in exception capture , At the same time, the exception of the closing process is appended to the outermost exception , And add code to close the flow at the end of the program .
After the flow is closed , The data is no longer written to the buffer , meanwhile nio Of In heap memory cache HeapByteBuffer The data in is still old . Whatever happens in the back flush Can not give effective feedback to the front end .

Previous recommendation 33 Mid year summary of year old programmers
Face slag counter attack :MySQL Sixty six questions ! Recommended collection
actual combat :10 A method to implement delayed tasks , The attached code !

边栏推荐
- How to grab the mobile phone bag for analysis? Fiddler artifact may help you!
- 二叉搜索树模板
- DP problem set
- 一个女孩子居然做了十年硬件。。。
- 如何抓手机的包进行分析,Fiddler神器或许能帮到您!
- leetcode:55. Jumping game [classic greed]
- Notes on writing questions (18) -- binary tree: common ancestor problem
- Multithreaded finalization
- 刷题笔记(十八)--二叉树:公共祖先问题
- leetcode:45. 跳跃游戏 II【经典贪心】
猜你喜欢

Guava中这些Map的骚操作,让我的代码量减少了50%

You are using pip version 21.1.2; however, version 22.1.2 is available

Flutter 如何使用在线转码工具将 JSON 转为 Model

面试官:你说你精通Redis,你看过持久化的配置吗?

是真干不过00后,给我卷的崩溃,想离职了...

零代码即可将数据可视化应用到企业管理中

降低pip到指定版本(通过PyCharm升级pip,在降低到原来版本)

You are using pip version 21.1.2; however, version 22.1.2 is available

Redis+Caffeine两级缓存,让访问速度纵享丝滑

leetcode:55. 跳跃游戏【经典贪心】
随机推荐
基于kruskal的最小生成树
[200 opencv routines] 209 Color image segmentation in HSV color space
嵌入式开发:技巧和窍门——干净地从引导加载程序跳转到应用程序代码
Rotate the square array of two-dimensional array clockwise by 90 °
Excel布局
降低pip到指定版本(通過PyCharm昇級pip,在降低到原來版本)
Getting started with typescript
leetcode_ one thousand three hundred and sixty-five
How to grab the mobile phone bag for analysis? Fiddler artifact may help you!
Principle and application of queue implementation
First order model realizes photo moving (with tool code) | machine learning
[theory] deep learning in the covid-19 epic: a deep model for urban traffic revitalization index
最大流问题
leetcode_ 191_ 2021-10-15
You are using pip version 21.1.2; however, version 22.1.2 is available
Cannot find reference 'imread' in 'appears in pycharm__ init__. py‘
[notes of wuenda] fundamentals of machine learning
CV2 package guide times could not find a version that satisfies the requirement CV2 (from versions: none)
心楼:华为运动健康的七年筑造之旅
You are using pip version 21.1.2; however, version 22.1.2 is available


