Handle removing trailing slash from path.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
* Copyright 2013-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -61,6 +61,12 @@ public class FeignClientProperties {
|
||||
*/
|
||||
private boolean decodeSlash = true;
|
||||
|
||||
/**
|
||||
* If {@code true}, trailing slashes at the end
|
||||
* of request urls will be removed.
|
||||
*/
|
||||
private boolean removeTrailingSlash;
|
||||
|
||||
public boolean isDefaultToProperties() {
|
||||
return defaultToProperties;
|
||||
}
|
||||
@@ -93,6 +99,14 @@ public class FeignClientProperties {
|
||||
this.decodeSlash = decodeSlash;
|
||||
}
|
||||
|
||||
public boolean isRemoveTrailingSlash() {
|
||||
return removeTrailingSlash;
|
||||
}
|
||||
|
||||
public void setRemoveTrailingSlash(boolean removeTrailingSlash) {
|
||||
this.removeTrailingSlash = removeTrailingSlash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
@@ -103,12 +117,13 @@ public class FeignClientProperties {
|
||||
}
|
||||
FeignClientProperties that = (FeignClientProperties) o;
|
||||
return defaultToProperties == that.defaultToProperties && Objects.equals(defaultConfig, that.defaultConfig)
|
||||
&& Objects.equals(config, that.config) && Objects.equals(decodeSlash, that.decodeSlash);
|
||||
&& Objects.equals(config, that.config) && Objects.equals(decodeSlash, that.decodeSlash)
|
||||
&& Objects.equals(removeTrailingSlash, that.removeTrailingSlash);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(defaultToProperties, defaultConfig, config, decodeSlash);
|
||||
return Objects.hash(defaultToProperties, defaultConfig, config, decodeSlash, removeTrailingSlash);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
* Copyright 2013-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -145,8 +145,7 @@ public class FeignClientsConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Contract feignContract(ConversionService feignConversionService) {
|
||||
boolean decodeSlash = feignClientProperties == null || feignClientProperties.isDecodeSlash();
|
||||
return new SpringMvcContract(parameterProcessors, feignConversionService, decodeSlash);
|
||||
return new SpringMvcContract(parameterProcessors, feignConversionService, feignClientProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;
|
||||
import org.springframework.cloud.openfeign.CollectionFormat;
|
||||
import org.springframework.cloud.openfeign.FeignClientProperties;
|
||||
import org.springframework.cloud.openfeign.SpringQueryMap;
|
||||
import org.springframework.cloud.openfeign.annotation.CookieValueParameterProcessor;
|
||||
import org.springframework.cloud.openfeign.annotation.MatrixVariableParameterProcessor;
|
||||
@@ -115,6 +116,8 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource
|
||||
|
||||
private final boolean decodeSlash;
|
||||
|
||||
private final boolean removeTrailingSlash;
|
||||
|
||||
public SpringMvcContract() {
|
||||
this(Collections.emptyList());
|
||||
}
|
||||
@@ -128,8 +131,32 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource
|
||||
this(annotatedParameterProcessors, conversionService, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SpringMvcContract} based on annotatedParameterProcessors,
|
||||
* conversionService and decodeSlash value.
|
||||
* @param annotatedParameterProcessors list of {@link AnnotatedParameterProcessor} objects used to resolve parameters
|
||||
* @param conversionService {@link ConversionService} used for type conversion
|
||||
* @param decodeSlash indicates whether slashes should be decoded
|
||||
* @deprecated in favour of {@link SpringMvcContract#SpringMvcContract(List, ConversionService, FeignClientProperties)}
|
||||
*/
|
||||
@Deprecated
|
||||
public SpringMvcContract(List<AnnotatedParameterProcessor> annotatedParameterProcessors,
|
||||
ConversionService conversionService, boolean decodeSlash) {
|
||||
this(annotatedParameterProcessors, conversionService, decodeSlash, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SpringMvcContract} based on annotatedParameterProcessors,
|
||||
* conversionService and decodeSlash value.
|
||||
* @param annotatedParameterProcessors list of {@link AnnotatedParameterProcessor} objects used to resolve parameters
|
||||
* @param conversionService {@link ConversionService} used for type conversion
|
||||
* @param decodeSlash indicates whether slashes should be decoded
|
||||
* @param removeTrailingSlash indicates whether trailing slashes should be removed
|
||||
* @deprecated in favour of {@link SpringMvcContract#SpringMvcContract(List, ConversionService, FeignClientProperties)}
|
||||
*/
|
||||
@Deprecated
|
||||
public SpringMvcContract(List<AnnotatedParameterProcessor> annotatedParameterProcessors,
|
||||
ConversionService conversionService, boolean decodeSlash, boolean removeTrailingSlash) {
|
||||
Assert.notNull(annotatedParameterProcessors, "Parameter processors can not be null.");
|
||||
Assert.notNull(conversionService, "ConversionService can not be null.");
|
||||
|
||||
@@ -140,6 +167,14 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource
|
||||
this.conversionService = conversionService;
|
||||
convertingExpanderFactory = new ConvertingExpanderFactory(conversionService);
|
||||
this.decodeSlash = decodeSlash;
|
||||
this.removeTrailingSlash = removeTrailingSlash;
|
||||
}
|
||||
|
||||
public SpringMvcContract(List<AnnotatedParameterProcessor> annotatedParameterProcessors,
|
||||
ConversionService conversionService, FeignClientProperties feignClientProperties) {
|
||||
this(annotatedParameterProcessors, conversionService,
|
||||
feignClientProperties == null || feignClientProperties.isDecodeSlash(),
|
||||
feignClientProperties != null && feignClientProperties.isRemoveTrailingSlash());
|
||||
}
|
||||
|
||||
private static TypeDescriptor createTypeDescriptor(Method method, int paramIndex) {
|
||||
@@ -229,6 +264,9 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource
|
||||
if (!pathValue.startsWith("/") && !data.template().path().endsWith("/")) {
|
||||
pathValue = "/" + pathValue;
|
||||
}
|
||||
if (removeTrailingSlash && pathValue.endsWith("/")) {
|
||||
pathValue = pathValue.substring(0, pathValue.length() - 1);
|
||||
}
|
||||
data.template().uri(pathValue, true);
|
||||
if (data.template().decodeSlash() != decodeSlash) {
|
||||
data.template().decodeSlash(decodeSlash);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
* Copyright 2013-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -90,7 +90,7 @@ class FeignClientsRegistrarTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeLastSlashOfUrl() {
|
||||
void testRemoveTrailingSlashFromUrl() {
|
||||
String url = FeignClientsRegistrar.getUrl("http://localhost/");
|
||||
assertThat(url).isEqualTo("http://localhost");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user