[英]Server side custom headers with embedded jetty and jersey
We have a legacy application that uses embedded Jetty and provides functionality through clients making HTTP calls. 我们有一个旧应用程序,该应用程序使用嵌入式Jetty并通过客户端进行HTTP调用来提供功能。 Most of the information/parameters needed by the server is sent by the client through HTTP headers.
服务器所需的大多数信息/参数由客户端通过HTTP标头发送。 We are now prototyping the use of REST API calls using Jersey where the same parameters are provided as JSON inputs.
现在,我们使用Jersey来原型化REST API调用的使用,其中提供与JSON输入相同的参数。 One of the requirements is to maintain backward compatibility and not disturb the existing functionality.
要求之一是保持向后兼容性,并且不干扰现有功能。
While we were able to use Jersey and pass in parameters, we are looking for help with the following: 尽管我们能够使用Jersey并传递参数,但我们在以下方面寻求帮助:
I have tried the other (very helpful) posts on using the wrapper/filter mechanisms to add custom headers, even one using the ContainterRequestFilter. 我已经尝试了其他(非常有帮助)的帖子,内容涉及使用包装器/过滤器机制添加自定义标头,甚至是一个使用ContainterRequestFilter的标头。 Following are my references:
以下是我的参考资料:
However for security reasons, the legacy application has this line of code (recommended in Jetty docs) which uses the base request instead of the wrapped request: 但是出于安全原因,旧版应用程序具有以下代码行(在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();
This effectively does not use the HttpServletRequestWrapper object that I send in. Since this line of code looks for the org.eclipse.jetty.server.Request
object, I tried creating a wrapper around this object, like so, but this did not work because this instance seems to have most of the content as null, plus it would not provide the rest of the methods that the Request object would provide. 这实际上不使用我发送的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);
}
}
What is the best way to send the JSON inputs in as headers from the REST handling method to the existing Jetty handlers, without creating security concerns? 将JSON输入作为标头从REST处理方法发送到现有Jetty处理程序的最佳方法是什么,而又不会引起安全问题? I guess I could tweak that check for the base request a bit, but I am not sure of the best way to do it.
我想我可以稍微调整一下基本请求的检查,但是我不确定做到这一点的最佳方法。
Wrapped requests are only valid for the same ServletContext
and Filter
chain that the wrapped request was created in and only applies to the rest of the executing Filter chain from the point in time it was created. 包装的请求仅对在其中创建包装请求的
ServletContext
和Filter
链有效,并且仅适用于从创建之时起执行的Filter链的其余部分。
A wrapped request will never apply to a standard Jetty Handler
, as that's not participating in a ServletContext
or Filter
chain. 包装的请求永远不会应用于标准的Jetty
Handler
,因为它不参与ServletContext
或Filter
链。
It is also impossible to wrap the core Jetty Request
object due to the needs of the context-less environment it executes within. 由于在其中执行的无上下文环境的需求,也无法包装核心Jetty
Request
对象。 You cannot change this behavior. 您无法更改此行为。
If you are wrapping requests and whatnot just to provide a custom request header, then stop doing ALL of the wrapping and nonsense you are dealing with right now. 如果要包装请求,而不仅仅是提供自定义请求标头,则立即停止处理您正在处理的所有包装和废话。
Note: The minute you stop wrapping
HttpServletRequest
,HttpServletResponse
, or the Servlet streams is the minute you will have the ability to use features introduced for Servlet 3.0 and newer, such as AsyncContext and Async I/O.注意:在停止包装
HttpServletRequest
,HttpServletResponse
或Servlet流的那一刻,您将可以使用为Servlet 3.0和更高版本引入的功能,例如AsyncContext和Async I / O。 The technique of wrapping these components is discouraged in modern usage because it limits your options for better performing webapps.在现代用法中不鼓励使用包装这些组件的技术,因为它限制了您选择性能更好的Web应用程序的选择。
You have 2 choices, both modify the Request headers in-place. 您有2个选择,都可以就地修改Request标头。
If you choose to modify the headers before dispatch, there are 2 places you can do this. 如果选择在发送前修改标头,则可以在2个地方执行此操作。
HttpConfiguration.Customizer
HttpConfiguration.Customizer
HttpChannel.Listener
events HttpChannel.Listener
事件之一期间 If you choose to modify the headers during dispatch, then create a Jetty Handler
that modifies the Request
headers, and put it somewhere early in your server handler hierarchy. 如果您选择在分发期间修改标头,则创建一个Jetty
Handler
来修改Request
标头,并将其放在服务器处理程序层次结构的早期。
The code that modifies the Request headers will all do the same thing, here's the Handler version as an example. 修改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");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.