Пользовательские заголовки на стороне сервера со встроенным причалом и трикотажем - PullRequest
1 голос
/ 04 июня 2019

У нас есть устаревшее приложение, которое использует встроенный Jetty и предоставляет функциональные возможности через клиентов, выполняющих HTTP-вызовы.Большая часть информации / параметров, необходимых серверу, отправляется клиентом через заголовки HTTP.Сейчас мы создаем прототип использования REST API-вызовов, используя Джерси, где те же параметры предоставляются в качестве входных данных JSON.Одно из требований - поддерживать обратную совместимость и не нарушать существующую функциональность.

Хотя мы смогли использовать Джерси и передать параметры, нам нужна помощь по следующим вопросам:

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, я попытался создать обертку вокруг этого объекта, например, но это не сработало, потому что этот экземпляр, похоже, имеет большую часть содержимого как ноль, плюс он не предоставил быостальные методы, которые должен предоставить объект 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без проблем с безопасностью?Думаю, я мог бы немного подправить эту проверку для базового запроса, но я не уверен, что это лучший способ сделать это.

1 Ответ

0 голосов
/ 05 июня 2019

Обернутые запросы действительны только для той же цепочки ServletContext и Filter, в которой был создан обернутый запрос, и применяются только к остальной части исполняемой цепочки фильтров с момента создания.

Обернутый запрос никогда не будет применяться к стандартному Jetty Handler, поскольку он не участвует в цепочке ServletContext или Filter.

Также невозможно обернуть основной объект Jetty Request из-за потребностей среды без контекста, в которой он выполняется. Вы не можете изменить это поведение.

Если вы упаковываете запросы и так далее, просто чтобы предоставить пользовательский заголовок запроса, прекратите делать ALL упаковки и бессмыслицы, с которыми вы сейчас имеете дело.

Примечание. В минуту, когда вы прекратите перенос HttpServletRequest, HttpServletResponse или потоков сервлетов, вы сможете использовать функции, представленные в Servlet 3.0 и новее, например AsyncContext и Async I / O. Техника обертывания этих компонентов не рекомендуется в современном использовании, потому что она ограничивает ваши возможности для более эффективных веб-приложений.

У вас есть 2 варианта, оба изменяют заголовки запроса на месте.

  1. Изменить заголовки запроса перед отправкой.
  2. Изменить заголовки запроса во время отправки через низкоуровневый обработчик Jetty.

Если вы решите изменить заголовки перед отправкой, есть 2 места, где вы можете сделать это.

  1. Как HttpConfiguration.Customizer
  2. Во время одной из предварительных отправок HttpChannel.Listener событий

Если вы решите изменить заголовки во время отправки, то создайте Jetty Handler, которая изменяет заголовки Request, и поместите его где-нибудь в начале иерархии вашего обработчика сервера.

Код, который изменяет заголовки запроса, будет делать то же самое, вот пример версии обработчика.

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");
    }
}
...