假装不编码参数
Feign not encoding param
我正在重构遗留代码库以使用 Feign,我遇到了一些问题:
没有一个 Feign 日志语句被打印到控制台
- 尽管使用记录器和完整日志级别实例化
Feign 没有对我的 reservationSearch 参数进行编码
- 假装只是
POST
toString
的 Object
Feign 定义:
public interface EPCReservationClient {
@RequestLine("POST v1/searchReservations")
@Headers({"clientId: {clientId}", "Content-Type: application/json",
"Authentication: {authentication}"})
@Body("{reservationSearch}")
ReservationSearchResponse reservationSearch(
@Param("authentication") String authentication, //apiToken
@Param("clientId") String clientId,
@Param("reservationSearch")
ReservationSearch<ReservationSearchParameters> reservationSearch);
}
Feign实例化
Feign.builder()
.logger(new Logger.JavaLogger())
.decoder(new JacksonDecoder())
.encoder(new JacksonEncoder(new ObjectMapper().findAndRegisterModules()))
.logLevel(Logger.Level.FULL)
.target(EPCReservationClient.class, restUrl);
参数类型(别杀我,不是我的代码):
public class ReservationSearch<T> {
@JsonProperty("hotelID")
private final int hotelID;
private final String languageId;
@JsonProperty("reservationSearchParameters")
private final T parameters;
@JsonProperty("reservationID")
private final List<Long> reservationID;
public ReservationSearch(int hotelID, T parameters, final List<Long> reservationID) {
this.hotelID = hotelID;
this.languageId = "1033";
this.parameters = parameters;
this.reservationID = Optional.ofNullable(reservationID)
.orElseGet(Collections::emptyList);
}
public static ReservationSearch<ReservationSearchParameters> forLastName(
int maxRecords, int hotelId, String lastName) {
return new ReservationSearch<>(hotelId, new ReservationSearchParameters(maxRecords, lastName, null), null);
}
public static ReservationSearch<ReservationSearchParameters> forConfirmationNumber(
int maxRecords, int hotelId, String number) {
return new ReservationSearch<>(hotelId, new ReservationSearchParameters(maxRecords, null, number), null);
}
public static ReservationSearch<ReservationSearchParameters> forReservationId(
final int maxRecords,
final int hotelId,
final String reservationNumber) {
ReservationSearch<ReservationSearchParameters> reservationSearchParametersReservationSearch = new ReservationSearch<>(
hotelId,
new ReservationSearchParameters(
maxRecords,
null,
null),
Collections.singletonList(Long.valueOf(reservationNumber)));
return reservationSearchParametersReservationSearch;
}
public int getHotelID() {
return hotelID;
}
public String getLanguageId() {
return languageId;
}
public T getParameters() {
return parameters;
}
public List<Long> getReservationID() {
return reservationID;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final ReservationSearch that = (ReservationSearch) o;
return new EqualsBuilder()
.append(hotelID, that.hotelID)
.append(languageId, that.languageId)
.append(parameters, that.parameters)
.append(reservationID, that.reservationID)
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(hotelID)
.append(languageId)
.append(parameters)
.append(reservationID)
.toHashCode();
}
}
预订搜索参数:
public class ReservationSearchParameters {
private final String travelerLastName;
private final String confirmationNumber;
private final int maxRecordsLimit;
public ReservationSearchParameters(int maxRecordsLimit, String travelerLastName, String confirmationNumber) {
this.maxRecordsLimit = maxRecordsLimit;
this.travelerLastName = travelerLastName;
this.confirmationNumber = confirmationNumber;
}
public String getTravelerLastName() { return travelerLastName; }
public String getConfirmationNumber() { return confirmationNumber; }
public int getMaxRecordsLimit() { return maxRecordsLimit; }
}
Header(@Headers
和 @HeaderMap
)和 body 模板(@Body
)参数始终被视为 pre-encoded。只有查询参数(@QueryMap
和 @Param
引用查询参数)将被 URL 编码。
如果您希望 body object 通过 Encoder
编码,则不要提供任何 @Body
模板,也不要注释您的 body 参数和 @Param
(仅用于模板参数)。然后 un-annotated body 参数将被馈送到 Feign.builder().encoder(new FooEncoder())
行中指定的 Encoder
。
我正在重构遗留代码库以使用 Feign,我遇到了一些问题:
没有一个 Feign 日志语句被打印到控制台
- 尽管使用记录器和完整日志级别实例化
Feign 没有对我的 reservationSearch 参数进行编码
- 假装只是
POST
toString
的Object
- 假装只是
Feign 定义:
public interface EPCReservationClient {
@RequestLine("POST v1/searchReservations")
@Headers({"clientId: {clientId}", "Content-Type: application/json",
"Authentication: {authentication}"})
@Body("{reservationSearch}")
ReservationSearchResponse reservationSearch(
@Param("authentication") String authentication, //apiToken
@Param("clientId") String clientId,
@Param("reservationSearch")
ReservationSearch<ReservationSearchParameters> reservationSearch);
}
Feign实例化
Feign.builder()
.logger(new Logger.JavaLogger())
.decoder(new JacksonDecoder())
.encoder(new JacksonEncoder(new ObjectMapper().findAndRegisterModules()))
.logLevel(Logger.Level.FULL)
.target(EPCReservationClient.class, restUrl);
参数类型(别杀我,不是我的代码):
public class ReservationSearch<T> {
@JsonProperty("hotelID")
private final int hotelID;
private final String languageId;
@JsonProperty("reservationSearchParameters")
private final T parameters;
@JsonProperty("reservationID")
private final List<Long> reservationID;
public ReservationSearch(int hotelID, T parameters, final List<Long> reservationID) {
this.hotelID = hotelID;
this.languageId = "1033";
this.parameters = parameters;
this.reservationID = Optional.ofNullable(reservationID)
.orElseGet(Collections::emptyList);
}
public static ReservationSearch<ReservationSearchParameters> forLastName(
int maxRecords, int hotelId, String lastName) {
return new ReservationSearch<>(hotelId, new ReservationSearchParameters(maxRecords, lastName, null), null);
}
public static ReservationSearch<ReservationSearchParameters> forConfirmationNumber(
int maxRecords, int hotelId, String number) {
return new ReservationSearch<>(hotelId, new ReservationSearchParameters(maxRecords, null, number), null);
}
public static ReservationSearch<ReservationSearchParameters> forReservationId(
final int maxRecords,
final int hotelId,
final String reservationNumber) {
ReservationSearch<ReservationSearchParameters> reservationSearchParametersReservationSearch = new ReservationSearch<>(
hotelId,
new ReservationSearchParameters(
maxRecords,
null,
null),
Collections.singletonList(Long.valueOf(reservationNumber)));
return reservationSearchParametersReservationSearch;
}
public int getHotelID() {
return hotelID;
}
public String getLanguageId() {
return languageId;
}
public T getParameters() {
return parameters;
}
public List<Long> getReservationID() {
return reservationID;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final ReservationSearch that = (ReservationSearch) o;
return new EqualsBuilder()
.append(hotelID, that.hotelID)
.append(languageId, that.languageId)
.append(parameters, that.parameters)
.append(reservationID, that.reservationID)
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(hotelID)
.append(languageId)
.append(parameters)
.append(reservationID)
.toHashCode();
}
}
预订搜索参数:
public class ReservationSearchParameters {
private final String travelerLastName;
private final String confirmationNumber;
private final int maxRecordsLimit;
public ReservationSearchParameters(int maxRecordsLimit, String travelerLastName, String confirmationNumber) {
this.maxRecordsLimit = maxRecordsLimit;
this.travelerLastName = travelerLastName;
this.confirmationNumber = confirmationNumber;
}
public String getTravelerLastName() { return travelerLastName; }
public String getConfirmationNumber() { return confirmationNumber; }
public int getMaxRecordsLimit() { return maxRecordsLimit; }
}
Header(@Headers
和 @HeaderMap
)和 body 模板(@Body
)参数始终被视为 pre-encoded。只有查询参数(@QueryMap
和 @Param
引用查询参数)将被 URL 编码。
如果您希望 body object 通过 Encoder
编码,则不要提供任何 @Body
模板,也不要注释您的 body 参数和 @Param
(仅用于模板参数)。然后 un-annotated body 参数将被馈送到 Feign.builder().encoder(new FooEncoder())
行中指定的 Encoder
。