- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我注意到每当handle
抛出异常时,Jetty
就会重试调用指定的Handler
。
这是不受欢迎的行为,但我似乎找不到阻止它的配置设置。
我已经使用 Jetty 一段时间了,但最近升级了我的环境以使用 9.4.9.v20180320
。这可能是也可能不是新行为,但我从未注意到它。
下面是一个简单的用例来说明我的问题。请注意,输出中有两行指示正文内容,但令人困惑的是,在第二次尝试时,正文为空。
public class JettyTest extends AbstractHandler
{
@Override
public void handle(String arg0, Request arg1, HttpServletRequest arg2, HttpServletResponse arg3)
throws IOException
{
//read request body into string
ByteArrayOutputStream bos = new ByteArrayOutputStream();
//apache commons copy
IOUtils.copy(arg1.getInputStream(), bos);
String body = new String(bos.toByteArray());
System.out.println("request body: " + body);
throw new NullPointerException();
}
public static void main(String args[])
throws Exception
{
Server server = new Server();
server.setHandler(new JettyTest());
LocalConnector localConnector = new LocalConnector(server);
server.addConnector(localConnector);
server.start();
String simpleRequest = "GET / http/1.1\r\nHost: localhost:0\r\nContent-Type: text/plain\r\nContent-Length: 2\r\n\r\nhi";
String response = localConnector.getResponse(simpleRequest);
server.join();
}
}
输出
2018-03-26 19:47:49.590:INFO:oejs.Server:main: Started @327ms
request body: hi
2018-03-26 19:47:49.660:WARN:oejs.HttpChannel:qtp1349277854-12: /
java.lang.NullPointerException
at test.JettyTest.handle(JettyTest.java:28)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.Server.handle(Server.java:531)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:352)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:281)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
at org.eclipse.jetty.io.ByteArrayEndPoint$1.run(ByteArrayEndPoint.java:78)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:754)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:672)
at java.lang.Thread.run(Thread.java:748)
request body:
最佳答案
你有很多事情正在发生。
Request.setHandled(true)
)所以发生的事情是......
如果您只是对此进行更改...
package jetty.errors;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.servlet.DispatcherType;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.IO;
public class HandlerWithError extends AbstractHandler
{
@Override
public void handle(String s, Request request, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException
{
if (DispatcherType.REQUEST.equals(httpServletRequest.getDispatcherType()))
{
// read request body into string
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// apache commons copy
IO.copy(httpServletRequest.getInputStream(), bos);
String body = new String(bos.toByteArray());
System.out.println("request body: " + body);
throw new NullPointerException();
}
else
{
System.out.println("Now in DispatchType: " + httpServletRequest.getDispatcherType());
}
}
public static void main(String args[])
throws Exception
{
Server server = new Server();
server.setHandler(new HandlerWithError());
LocalConnector localConnector = new LocalConnector(server);
server.addConnector(localConnector);
server.start();
String simpleRequest = "GET / http/1.1\r\n" +
"Host: localhost:0\r\n" +
"Connection: close\r\n" +
"Content-Type: text/plain\r\n" +
"Content-Length: 2\r\n\r\nhi";
String response = localConnector.getResponse(simpleRequest);
server.join();
}
}
你会得到结果...
2018-03-27 06:47:40.074:INFO::main: Logging initialized @429ms to org.eclipse.jetty.util.log.StdErrLog
2018-03-27 06:47:40.148:INFO:oejs.Server:main: jetty-9.4.9.v20180320; built: 2018-03-20T07:21:10-05:00; git: 1f8159b1e4a42d3f79997021ea1609f2fbac6de5; jvm 9.0.4+11
2018-03-27 06:47:40.182:INFO:oejs.AbstractConnector:main: Started LocalConnector@2f490758{HTTP/1.1,[http/1.1]}
2018-03-27 06:47:40.183:INFO:oejs.Server:main: Started @548ms
2018-03-27 06:47:40.287:WARN:oejs.HttpChannel:qtp2104545713-16: /
java.lang.NullPointerException
at jetty.errors.HandlerWithError.handle(HandlerWithError.java:29)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.Server.handle(Server.java:531)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:352)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:281)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
at org.eclipse.jetty.io.ByteArrayEndPoint$1.run(ByteArrayEndPoint.java:78)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:754)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:672)
at java.base/java.lang.Thread.run(Thread.java:844)
request body: hi
Now in DispatchType: ERROR
了解了这一切后,您可以通过以下方式更改您的实现以利用此 ERROR 调度。
package jetty.errors;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.servlet.DispatcherType;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.util.IO;
public class HandlerWithError
{
public static class MyRequestHandler extends AbstractHandler
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
{
System.out.println("MyRequestHandler.handle() - DispatcherType: " + request.getDispatcherType());
// only work with REQUEST Dispatches
if (!DispatcherType.REQUEST.equals(request.getDispatcherType()))
{
// skip this handler
return;
}
// Set handled (by this handler), don't let other handlers operate on this request
baseRequest.setHandled(true);
// read request body into string
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// apache commons copy
IO.copy(request.getInputStream(), bos);
String body = new String(bos.toByteArray());
System.out.println("request body: " + body);
throw new NullPointerException();
}
}
public static class MyErrorHandler extends AbstractHandler
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
{
System.out.println("MyErrorHandler.handle() - DispatcherType: " + request.getDispatcherType());
if(!DispatcherType.ERROR.equals(request.getDispatcherType()))
{
// skip this handler
return;
}
baseRequest.setHandled(true);
response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
response.setContentType("text/plain");
response.getWriter().println("Go away, you silly NPE fool");
}
}
public static void main(String args[])
throws Exception
{
Server server = new Server();
HandlerList handlers = new HandlerList();
// Add your ERROR Dispatch handler first to handle dispatches for errors
handlers.addHandler(new MyErrorHandler());
// Add your handlers here (can be more then one)
handlers.addHandler(new MyRequestHandler());
// Always add DefaultHandler last, to ensure that something in your handler
// list is calling baseRequest.setHandled(true)
handlers.addHandler(new DefaultHandler());
server.setHandler(handlers);
LocalConnector localConnector = new LocalConnector(server);
server.addConnector(localConnector);
server.start();
try
{
String simpleRequest = "GET / http/1.1\r\n" +
"Host: localhost:0\r\n" +
"Connection: close\r\n" +
"Content-Type: text/plain\r\n" +
"Content-Length: 2\r\n\r\nhi";
HttpTester.Response response = HttpTester.parseResponse(
localConnector.getResponse(simpleRequest));
System.out.println("Response: " + response);
System.out.println(response.getContent());
}
catch (Throwable t)
{
t.printStackTrace();
}
finally
{
server.stop();
}
}
}
输出看起来像这样......
2018-03-27 07:03:25.220:INFO::main: Logging initialized @320ms to org.eclipse.jetty.util.log.StdErrLog
2018-03-27 07:03:25.288:INFO:oejs.Server:main: jetty-9.4.9.v20180320; built: 2018-03-20T07:21:10-05:00; git: 1f8159b1e4a42d3f79997021ea1609f2fbac6de5; jvm 9.0.4+11
2018-03-27 07:03:25.309:INFO:oejs.AbstractConnector:main: Started LocalConnector@4ba2ca36{HTTP/1.1,[http/1.1]}
2018-03-27 07:03:25.310:INFO:oejs.Server:main: Started @417ms
MyErrorHandler.handle() - DispatcherType: REQUEST
MyRequestHandler.handle() - DispatcherType: REQUEST
request body: hi
2018-03-27 07:03:25.399:WARN:oejs.HttpChannel:qtp525571-15: /
java.lang.NullPointerException
at jetty.errors.HandlerWithError$MyRequestHandler.handle(HandlerWithError.java:41)
at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:61)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.Server.handle(Server.java:531)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:352)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:281)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
at org.eclipse.jetty.io.ByteArrayEndPoint$1.run(ByteArrayEndPoint.java:78)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:754)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:672)
at java.base/java.lang.Thread.run(Thread.java:844)
MyErrorHandler.handle() - DispatcherType: ERROR
Response: HTTP/1.1 503 Service Unavailable
Connection: close
Content-Type: text/plain;charset=ISO-8859-1
Content-Length: 29
Server: Jetty(9.4.9.v20180320)
Go away, you silly NPE fool
2018-03-27 07:03:25.423:INFO:oejs.AbstractConnector:main: Stopped LocalConnector@4ba2ca36{HTTP/1.1,[http/1.1]}
关于java - 当 RequestHandler 抛出异常时 Jetty 重试请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49502363/
我正在尝试从该网站抓取历史天气数据: http://www.hko.gov.hk/cis/dailyExtract_uc.htm?y=2016&m=1 在阅读了 AJAX 调用后,我发现请求数据的正确
我有两个 postman 请求 x,y,它们命中了两个不同的休息 api X,Y 中的端点。 x 会给我一个身份验证 token ,这是发出 y 请求所必需的。如何在请求 y 中发出请求 x ?也就是
我使用请求库通过 API 与其他服务器进行通信。但现在我需要同时发送多个(10 个或更多)POST 请求,并且只有在所有响应都正确的情况下才能进一步前进。通常语法看起来有点像这样: var optio
背景:当用户单击按钮时,其类会在class1和class2之间切换,并且此数据是通过 AJAX 提交。为了确认此数据已保存,服务器使用 js 进行响应(更新按钮 HTML)。 问题:如果用户点击按钮的
我正在将 Node.js 中的请求库用于 Google 的文本转语音 API。我想打印出正在发送的请求,如 python example . 这是我的代码: const request = requi
我经常使用requests。最近我发现还有一个 requests2 和即将到来的 requests3 虽然有一个 page其中简要提到了 requests3 中的内容,我一直无法确定 requests
我正在尝试将图像发送到我的 API,然后从中获取结果。例如,我使用发送一个 bmp 图像文件 file = {"img": open("img.bmp)} r = requests.post(url,
我发现 Google Cloud 确保移出其物理环境的任何请求都经过强制加密,请参阅(虚拟机到虚拟机标题下的第 6 页)this link Azure(和 AWS)是否遵循类似的程序?如果有人能给我指
我有一个 ASP.NET MVC 应用程序,我正在尝试在 javascript 函数中使用 jQuery 来创建一系列操作。该函数由三部分组成。 我想做的是:如果满足某些条件,那么我想执行同步 jQu
我找不到如何执行 get http 请求,所以我希望你们能帮助我。 这个想法是从外部url(例如 https://api.twitter.com/1.1/search/tweets.json?q=tw
我的应用只需要使用“READ_SMS”权限。我的问题是,在 Android 6.0 上,当我需要使用新的权限系统时,它会要求用户“发送和查看短信”。 这是我的代码: ActivityCompat.re
我的前端代码: { this.searchInput = input; }}/> 搜索 // search method: const baseUrl = 'http://localho
我有一个由 AJAX 和 C# 应用程序使用的 WCF 服务, 我需要通过 HTTP 请求 header 发送一个参数。 在我的 AJAX 上,我添加了以下内容并且它有效: $.ajax({
我正在尝试了解如何使用 promises 编写代码。请检查我的代码。这样对吗? Node.js + 请求: request(url, function (error, response, body)
如果失败(除 HTTP 200 之外的任何响应代码),我需要重试发送 GWT RPC 请求。原因很复杂,所以我不会详细说明。到目前为止,我在同一个地方处理所有请求响应,如下所示: // We
当用户单击提交按钮时,我希望提交表单。然而,就在这种情况发生之前,我希望弹出一个窗口并让他们填写一些数据。一旦他们执行此操作并关闭该子窗口,我希望发出 POST 请求。 这可能吗?如果可能的话如何?我
像 Facebook 这样的网站使用“延迟”加载 js。当你必须考虑到我有一台服务器,流量很大时。 我很感兴趣 - 哪一个更好? 当我一次执行更多 HTTP 请求时 - 页面加载速度较慢(由于限制(一
Servlet 容器是否创建 ServletRequest 和 Response 对象或 Http 对象?如果是ServletRequest,谁在调用服务方法之前将其转换为HttpServletReq
这是维基百科文章的摘录: In contrast to the GET request method where only a URL and headers are sent to the serv
我有一个循环,每次循环时都会发出 HTTP post 请求。 for(let i = 1; i console.log("succes at " + i), error => con
我是一名优秀的程序员,十分优秀!