SpringBoot アプリケーションがあり、Jersey を使用して受信 HTTP リクエストを監査しています。
Jersey ContainerRequestFilterを実装して着信HttpServletRequestを取得し 、HttpServletRequest のgetParameterMap()メソッドを使用してクエリとフォーム データの両方を抽出し、監査に配置しました。
これは、getParameterMap() の javadoc と一致します。
「リクエスト パラメータは、リクエストとともに送信される追加情報です。HTTP サーブレットの場合、パラメータはクエリ文字列または投稿されたフォーム データに含まれています。」
フィルタに関するドキュメントは次のとおりです。
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() {
...
}
}
完全な例
サンプル プロジェクトで再作成する手順は次のとおりです。
- ここで github からソースをダウンロードします。
git clone https://github.com/fei0x/so-jerseyBodyIssue
- pom.xml ファイルがあるプロジェクト ディレクトリに移動します。
- 次を使用してプロジェクトを実行します。
mvn -Prun
- 新しいターミナルで次の curl コマンドを実行して、Web サービスをテストします。
curl -X POST \ http://localhost:8012/api/jerseyBody/ping \ -H 'content-type: application/x-www-form-urlencoded' \ -d param=Test%20String
- ログにフォームパラメータが表示されます
- 実行中のプロジェクトを停止、ctrl-C
- 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>
- プロジェクトを再度実行します。
mvn -Prun
- curl 呼び出しを再度呼び出します。
curl -X POST \ http://localhost:8012/api/jerseyBody/ping \ -H 'content-type: application/x-www-form-urlencoded' \ -d param=Test%20String
- 今回は、ログにフォーム パラメータがありません