【问题标题】:How to read request headers from incoming message in a graphQL endpoint in spring boot application如何在 Spring Boot 应用程序中从 graphQL 端点中的传入消息中读取请求标头
【发布时间】:2019-06-19 16:33:21
【问题描述】:

我有一个使用 graphql 端点运行的 Spring Boot 应用程序,该端点验证并执行查询和突变,但是,我需要读取传入消息中的一个标头,以便将其值传递给另一个端点。 graphql 有没有办法读取这些值?某种 getHeaders 或类似的东西?

【问题讨论】:

  • 取决于您如何通过 HTTP 公开 GraphQL。您是否使用 servlet、spring mvc 或其他库公开它?
  • 我正在使用 spring boot graphql starter 和 graphql-java-tools maven 依赖项,我只需要实现 GraphQLMutationResolver 类

标签: java spring-boot graphql


【解决方案1】:

不是对您的问题陈述的直接回答,但可以在请求到达解析器端点之前使用过滤器来处理它(如果这是要求的话):

public class HeaderFilter implements Filter {

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
    final HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
    
    String headerVal= httpServletRequest.getHeader("<header string>");
    
    try {
        filterChain.doFilter(httpServletRequest, servletResponse);
    } catch (IOException | ServletException e) {
        //handle as you wish
    }
}

【讨论】:

    【解决方案2】:

    Google 给我带来了这个答案,不幸的是它是针对 Spring 框架的。许多人使用 Spring 框架,但如果你像我一样使用 Apache Tomcat 和 GraphQL 集成,你可以使用它。

            graphql.kickstart.servlet.context.DefaultGraphQLServletContext.DefaultGraphQLServletContext context =  dataFetchingEnvironment.getContext();
            jakarta.servlet.http.HttpServletRequest request = context.getHttpServletRequest();
            String tokenBearer = request.getHeader("Authorization");
    

    【讨论】:

      【解决方案3】:

      显然上下文的类型不是标准化的。我使用 SPQR,就我而言,我发现(通过调试):

              DefaultGlobalContext<ServletWebRequest> context = handlerParameters.getDataFetchingEnvironment().getContext();
              context.getNativeRequest().getHeader("something");
      

      【讨论】:

        【解决方案4】:

        @Ken Chan 的解决方案对我不起作用。 GraphQLContext 没有名为 getHttpServletRequest 的方法。
        改用GraphQLServletContext 解决了这个问题。您可以将代码更改为:

        public Foo resolveFoo(Map<String,String> input , DataFetchingEnvironment env){
        
            GraphQLServletContext context =  env.getContext();
            String header = context.getHttpServletRequest().getHeader("content-type");
        }
        

        【讨论】:

          【解决方案5】:

          GraphQL 本身并没有定义任何与如何通过网络公开相关的东西,因此它也没有定义任何与获取 HTTP 头相关的东西。这取决于开发人员使用他们的方式。所以,它取决于底层用于通过 HTTP 提供 GraphQL 的技术。

          假设您使用 graphql-spring-bootgraphql-java-tools ,并且假设您没有自定义 GraphQLContext ,您可以尝试将 DataFetchingEnvironment 参数添加到解析器函数中,然后从中获取 GraphQLContext 。然后,您可以从上下文中获取 HttpServletRequest 并访问标题:

              public Foo resolveFoo(Map<String,String> input , DataFetchingEnvironment env){
          
                  GraphQLContext context =  env.getContext();
                  HttpServletRequest request = context.getHttpServletRequest().get();
                  request.getHeader("content-type");
              }
          

          【讨论】:

          • 非常感谢!完美运行,这正是我需要做的
          • env.getContext() 为我返回 null。我在 DataFetcher 中使用它。你能帮忙吗?
          • @ArjunNayak 你是怎么解决这个问题的...
          • @user1912935 我使用了下面的代码 final GraphQLServletContext ctx = env.getContext();最终的 HttpServletRequest 请求 = ctx.getHttpServletRequest();
          • 但是正如您在之前的评论中提到的,您的 env.getContext() 和 HttpServletRequest request = ctx.getHttpServletRequest(); 为空。抛出空指针是不是......你是怎么解决空的......?
          猜你喜欢
          • 2020-05-23
          • 2018-10-31
          • 1970-01-01
          • 1970-01-01
          • 2017-06-29
          • 2019-12-26
          • 1970-01-01
          • 2018-07-07
          • 1970-01-01
          相关资源
          最近更新 更多