3

SpringBoot アプリケーションがあり、Jersey を使用して受信 HTTP リクエストを監査しています。

Jersey ContainerRequestFilterを実装して着信HttpServletRequestを取得し 、HttpServletRequest のgetParameterMap()メソッドを使用してクエリとフォーム データの両方を抽出し、監査に配置しました。

これは、getParameterMap() の javadoc と一致します。

「リクエスト パラメータは、リクエストとともに送信される追加情報です。HTTP サーブレットの場合、パラメータはクエリ文字列または投稿されたフォーム データに含まれています。」

フィルタに関するドキュメントは次のとおりです。

https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/user-guide.html#filters-and-interceptors

SpringBoot を更新すると、getParameterMap()がフォーム データを返さなくなりましたが、引き続きクエリ データを返すことがわかりました。

SpringBoot 2.1 が、コードをサポートする最後のバージョンであることがわかりました。SpringBoot 2.2 では、Jersey のバージョンが 2.29 に更新されましたが、リリース ノートを確認すると、これに関連するものは何も見つかりません。

何が変わったのですか?SpringBoot 2.2 / Jersey 2.29 をサポートするには、何を変更する必要がありますか?

以下は、コードの単純化されたバージョンです。

JerseyRequestFilter - 私たちのフィルター

import javax.annotation.Priority;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;
import javax.ws.rs.ext.Provider;
...

@Provider
@Priority(Priorities.AUTHORIZATION)
public class JerseyRequestFilter implements ContainerRequestFilter {

    @Context
    private ResourceInfo resourceInfo;

    @Context
    private HttpServletRequest httpRequest;
    ...
    
    public void filter(ContainerRequestContext context) throws IOException {
        ...
        requestData =  new RequestInterceptorModel(context, httpRequest, resourceInfo);
        ...
    }   
    ...
}   

RequestInterceptorModel - マップにはフォーム データが取り込まれておらず、クエリ データのみが取り込まれています

import lombok.Data;
import org.glassfish.jersey.server.ContainerRequest;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ResourceInfo;
...

@Data
public class RequestInterceptorModel {

    private Map<String, String[]> parameterMap;
    ...
    
    public RequestInterceptorModel(ContainerRequestContext context, HttpServletRequest httpRequest, ResourceInfo resourceInfo) throws AuthorizationException, IOException {
        ...
        setParameterMap(httpRequest.getParameterMap());
        ...
    }
    ...     
}

JerseyConfig - 私たちの設定

import com.xyz.service.APIService;
import io.swagger.jaxrs.config.BeanConfig;
import io.swagger.jaxrs.listing.ApiListingResource;
import io.swagger.jaxrs.listing.SwaggerSerializers;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.wadl.internal.WadlResource;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
...

@Component
public class JerseyConfig extends ResourceConfig {
    ...

    public JerseyConfig() {
        this.register(APIService.class);
        ...
        // Access through /<Jersey's servlet path>/application.wadl
        this.register(WadlResource.class);
        this.register(AuthFilter.class);
        this.register(JerseyRequestFilter.class);
        this.register(JerseyResponseFilter.class);
        this.register(ExceptionHandler.class);
        this.register(ClientAbortExceptionWriterInterceptor.class);
    }

    @PostConstruct
    public void init() 
        this.configureSwagger();
    }

    private void configureSwagger() {
        ...
    }
}

完全な例

サンプル プロジェクトで再作成する手順は次のとおりです。

  1. ここで github からソースをダウンロードします。
 git clone https://github.com/fei0x/so-jerseyBodyIssue
  1. pom.xml ファイルがあるプロジェクト ディレクトリに移動します。
  2. 次を使用してプロジェクトを実行します。
 mvn -Prun
  1. 新しいターミナルで次の curl コマンドを実行して、Web サービスをテストします。
  curl -X POST \
  http://localhost:8012/api/jerseyBody/ping \
  -H 'content-type: application/x-www-form-urlencoded' \
  -d param=Test%20String
  1. ログにフォームパラメータが表示されます
  2. 実行中のプロジェクトを停止、ctrl-C
  3. pom の親バージョンを SpringBoot の新しいバージョンに更新する
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.15.RELEASE</version>

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.9.RELEASE</version>
  1. プロジェクトを再度実行します。
 mvn -Prun
  1. curl 呼び出しを再度呼び出します。
  curl -X POST \
  http://localhost:8012/api/jerseyBody/ping \
  -H 'content-type: application/x-www-form-urlencoded' \
  -d param=Test%20String
  1. 今回は、ログにフォーム パラメータがありません
4

2 に答える 2