Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 带有嵌入式jetty和jersey的服务器端自定义标头_Java_Jersey_Jax Rs_Jetty - Fatal编程技术网

Java 带有嵌入式jetty和jersey的服务器端自定义标头

Java 带有嵌入式jetty和jersey的服务器端自定义标头,java,jersey,jax-rs,jetty,Java,Jersey,Jax Rs,Jetty,我们有一个使用嵌入式Jetty的遗留应用程序,通过客户端进行HTTP调用提供功能。服务器所需的大多数信息/参数由客户端通过HTTP头发送。我们现在正在使用Jersey原型化RESTAPI调用的使用,在Jersey中,相同的参数作为JSON输入提供。其中一个要求是保持向后兼容性,并且不干扰现有功能 虽然我们能够使用Jersey并传入参数,但我们正在寻求以下方面的帮助: 我们希望避免更改应用程序中当前的jetty处理程序,因此我们希望将RESTAPI输入中的json输入转换为头文件,并将其传递给处

我们有一个使用嵌入式Jetty的遗留应用程序,通过客户端进行HTTP调用提供功能。服务器所需的大多数信息/参数由客户端通过HTTP头发送。我们现在正在使用Jersey原型化RESTAPI调用的使用,在Jersey中,相同的参数作为JSON输入提供。其中一个要求是保持向后兼容性,并且不干扰现有功能

虽然我们能够使用Jersey并传入参数,但我们正在寻求以下方面的帮助:

  • 我们希望避免更改应用程序中当前的jetty处理程序,因此我们希望将RESTAPI输入中的json输入转换为头文件,并将其传递给处理程序,以便当前功能可以从这一点开始发挥作用
  • 我已经尝试了其他(非常有用的)文章,使用包装器/过滤器机制来添加自定义标题,甚至还有一篇使用ContainerRequestFilter的文章。以下是我的推荐信:

  • 但是,出于安全原因,遗留应用程序有以下代码行(Jetty docs中建议使用),它使用基本请求而不是包装请求:

这实际上没有使用我发送的HttpServletRequestWrapper对象。由于这行代码查找
org.eclipse.jetty.server.Request
对象,因此我尝试围绕此对象创建一个包装器,就像这样,但这不起作用,因为此实例的大部分内容似乎为null,而且它不会提供请求对象将提供的其余方法

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处理程序而不产生安全问题的最佳方式是什么?我想我可以稍微调整一下基本请求的检查,但我不确定最好的方法。

包装请求仅对创建包装请求所在的
ServletContext
Filter
链有效,并且仅适用于从创建包装请求的时间点开始执行的过滤器链的其余部分

包装请求永远不会应用于标准Jetty
处理程序
,因为它不参与
ServletContext
过滤器

由于核心Jetty
Request
对象在其中执行的无上下文环境的需要,因此也不可能包装该对象。您无法更改此行为

如果您正在包装请求等等,而不仅仅是为了提供一个定制的请求头,那么请停止现在正在处理的所有包装和废话

注意:停止包装
HttpServletRequest
HttpServletResponse
或Servlet流的那一刻,就是您能够使用Servlet 3.0及更新版本引入的功能的那一刻,例如AsyncContext和Async I/O。在现代使用中,包装这些组件的技术是不受鼓励的,因为它限制了您选择更好地执行Web应用程序

您有两个选择,都可以修改请求头

  • 在分派之前修改请求头
  • 通过低级Jetty处理程序在分派期间修改请求头
  • 如果您选择在分派之前修改标题,则可以在两个位置执行此操作

  • 作为一个
  • 在其中一个预调度事件期间
  • 如果您选择在分派过程中修改标头,则创建一个Jetty来修改
    请求
    标头,并将其放在服务器处理程序层次结构的早期位置

    修改请求头的代码都将执行相同的操作,以下是处理程序版本的示例

    package jetty.demo;
    导入java.io.IOException;
    导入javax.servlet.ServletException;
    导入javax.servlet.http.HttpServletRequest;
    导入javax.servlet.http.HttpServletResponse;
    导入org.eclipse.jetty.http.HttpField;
    导入org.eclipse.jetty.http.HttpHeader;
    导入org.eclipse.jetty.http.HttpStatus;
    导入org.eclipse.jetty.server.Request;
    导入org.eclipse.jetty.server.handler.AbstractHandler;
    导入org.eclipse.jetty.server.handler.HandlerWrapper;
    公共类ModifyRequestHeaderHandler扩展了AbstractHandler
    {
    @凌驾
    公共无效句柄(字符串目标、请求baseRequest、,
    HttpServletRequest请求,HttpServletResponse响应)
    抛出IOException、ServletException
    {
    //完全丰满的田野
    最终HttpField X_MY_测试=新HttpField(“X-MY-TEST”、“MyName”);
    baseRequest.getHttpFields().put(X_MY_测试);
    //作为预定义的标题和自定义值
    baseRequest.getHttpFields().put(HttpHeader.X由,
    “修改后的请求标题”);
    //作为字符串头和字符串值
    baseRequest.getHttpFields().put(“X-Foo-Test”、“MyFooName”);
    }
    }
    
    谢谢你,Joakim!我想我遗漏的关键是HttpFields部分。看起来像是添加了一个标题并将其发送出去。
    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);
       }
    }