我们有一个旧应用程序,该应用程序使用嵌入式Jetty并通过客户端进行HTTP调用来提供功能。服务器所需的大多数信息/参数由客户端通过HTTP标头发送。现在,我们使用Jersey来原型化REST API调用的使用,其中提供与JSON输入相同的参数。要求之一是保持向后兼容性,并且不干扰现有功能。
虽然我们能够使用Jersey并传递参数,但我们在以下方面寻求帮助:
我尝试了其他(非常有用的)关于使用包装器/过滤器机制添加自定义标头的文章,甚至其中一个使用ContainterRequestFilter。以下是我的参考资料:
但是出于安全原因,旧版应用程序具有以下代码行(在Jetty文档中建议),该代码行使用基本请求而不是包装请求:
Request base_request = request instanceof Request ? (Request)request : HttpConnection.getCurrentConnection().getHttpChannel().getRequest();
Response base_response = response instanceof Response ? (Response)response : HttpConnection.getCurrentConnection().getHttpChannel().getResponse();
这实际上不使用我发送的HttpServletRequestWrapper对象。由于此行代码查找org.eclipse.jetty.server.Request
对象,因此我尝试围绕该对象创建包装器,但是这样做没有用,因为实例似乎大部分内容为null,再加上它不会提供Request对象将提供的其余方法。
class MyRequestWrapper extends Request
{
public MyRequestWrapper(HttpServletRequest request)
{
super( ((Request)request).getHttpChannel(), ((Request)request).getHttpInput());
}
@Override
public String getHeader(String name)
{
if(name.equalsIgnoreCase("X-My-Test"))
{
return "MyName";
}
return super.getHeader(name);
}
}
将JSON输入作为标头从REST处理方法发送到现有Jetty处理程序的最佳方法是什么,而又不会引起安全问题?我想我可以稍微调整一下基本请求的检查,但是我不确定执行此请求的最佳方法。
答案 0 :(得分:0)
被包装的请求仅对在其中创建被包装的请求的同一ServletContext
和Filter
链有效,并且仅从创建之时起才应用于其余正在执行的Filter链。
包装请求永远不会应用于标准码头Handler
,因为它不参与ServletContext
或Filter
链。
由于在其中执行的无上下文环境的需求,因此也无法包装核心Jetty Request
对象。您无法更改此行为。
如果您要包装请求,而不仅仅是提供自定义请求标头,请立即停止对您正在处理的包装和废话的所有操作。
注意:停止包装
HttpServletRequest
,HttpServletResponse
或Servlet流的那一刻,您将有能力使用Servlet 3.0及更高版本中引入的功能,例如AsyncContext和AsyncI。 / O。在现代用法中不鼓励使用包装这些组件的技术,因为它限制了您选择性能更好的Web应用程序的可能性。
您有2个选择,都可以就地修改Request标头。
如果您选择在发送前修改标头,则可以在2个地方执行此操作。
如果您选择在分发期间修改标头,则创建一个修改Request
标头的Jetty Handler
,并将其放在服务器处理程序层次结构的早期。
修改Request标头的代码将做相同的事情,这里以Handler版本为例。
package jetty.demo;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.HandlerWrapper;
public class ModifyRequestHeadersHandler extends AbstractHandler
{
@Override
public void handle(String target, Request baseRequest,
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
// As fully fleshed out field
final HttpField X_MY_TEST = new HttpField("X-My-Test", "MyName");
baseRequest.getHttpFields().put(X_MY_TEST);
// As predefined header and custom value
baseRequest.getHttpFields().put(HttpHeader.X_POWERED_BY,
"ModifiedRequestHeadersHandler");
// As string header and string value
baseRequest.getHttpFields().put("X-Foo-Test", "MyFooName");
}
}