写入输出流处理过程中出错
我正在构建一个 httpserver 作为我的 java 学术课程的一部分, 服务器应该只支持基本的 GET 和 POST 请求。
我想知道是否有一种优雅的方法来处理将 html 文件流内容(以及在我已经发送响应标头之后)写入 HttpServer 输出流中间发生的错误。
通过优雅的方式,我指的是向用户显示或重定向到“内部服务器错误”错误页面。
我尝试重新发送带有 501 错误代码的 http 响应标头,但 java 抛出一个异常,声称标头已发送...
一种修复方法是将文件的内容读入内存,然后才发送标头和内容,但可能会出现其他问题,而且,我不想在将大文件作为响应发送出去之前将它们加载到内存中。
I'm building an httpserver as part of my academic java course,
The server should only support basic GET and POST requests.
I was wondering if there's an elegant way to handle an error which occures in the middle of writing an html file stream content (and after I've already sent the response headers) into the HttpServer output stream.
By elegant way I refer to showing or redirecting the user to a "Internal Server Error" error page.
I tried re-sending the http response headers with 501 error code, but java throws an exception which claims that the headers were already sent...
One fix would be to read the file's contents into memory, and only then sending the headers and the content, but other problems can arise, and furthermore, I don't want to load huge files into the memory before sending them out as a response.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
响应状态一旦通过网络发送,就无法更改。因此,如果您发送了
200 OK
响应,之后您就无法改变主意。正如您所发现的,如果响应过程中发生错误,这就会出现问题。据我所知,您唯一能做的就是发送分块响应。请参阅 RFC 2616 第 3.6.1 节:
该预告片的目的是提供在发送实体主体之前无法计算的有关实体主体的信息。然而,第 7.1 节允许在此预告片中包含任何标头:
因此,虽然您可以在响应期间发出错误信号,但必须在两个部分之间就如何发出信号达成一致。一般来说,您不能使用任何假设客户端会理解为发出错误情况信号的方法。
在带有
Content-length
标头的消息中提前结束连接是一种选择,但这是明确禁止的:也就是说,虽然服务器发送的消息不得短于其所通告的消息,但客户端必须检查此错误情况并据此进行报告(代理甚至可以缓存此部分响应)。
Once the response status is sent on the wire, it cannot be changed. So if you sent a
200 OK
response, you cannot change your mind afterwards. As you found, this presents a problem in case of errors that occur mid response.As far as I know, the only think you can do is to send a chunked response. See section 3.6.1 of RFC 2616:
The purpose of this trailer is to give information about the entity body that cannot be calculated before the entity body is sent. However, section 7.1 allows any header to be included in this trailer:
So while you can signal that an error has occurred mid response, it must be conventioned between the two parts how this is signaled. You cannot, in general, use any method you can assume the client will understand as signaling an error condition.
Ending the connection prematurely in a message with a
Content-length
header is an option, but one that is explicitly forbidden:That said, while the server must not send a message shorter than he advertises, the client must check for this error condition and reported as such (and proxies may even cache this partial response).
如果您无法发送“成功”响应,您将如何发送不同的响应?您所能做的就是记录下来然后忘记它。
If you can't send the 'success' response how are you going to send a different response? All you can do is log it and forget about it.