Ausgabe
Meine Anwendung verwendet Spring-Boot 2.5.5.
Ich habe beim Start der Anwendung eine Eigenschaft für Tomcat festgelegt, um codierten Schrägstrich zuzulassen@PathVariable
:
@SpringBootApplication
public class App {
public static void main(String[] args) {
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
SpringApplication.run(App.class, args);
}
}
Alles funktioniert gut, wenn ich die App starte, außer in meinen Integrationstests:
@ActiveProfiles("test-connected")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@ExtendWith(SpringExtension.class)
class GlobalFullTest {
Wenn ich die org.apache.tomcat.util.buf.UDecoder
Klasse debugge: Ich sehe, dass die Eigenschaft org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH
ist null
, wenn die Klasse geladen wird, also wird ein Standardwert false
festgelegt.
Folgendes habe ich versucht:
- Hinzufügen
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
der@BeforeAll
Methode meines Tests - Hinzufügen
properties = { "org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true" }
der@SpringBootTest
Anmerkung. - Meine
org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH: true
hinzufügenapplication-test-connected.yaml
- Verwendung
WebServerFactoryCustomizer
:
@Configuration
public class WebServerConfiguration {
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> customizer() {
return factory -> factory.addConnectorCustomizers(connector -> connector.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true"));
}
}
Aber nichts davon hat funktioniert: Wenn die Eigenschaft nach org.apache.tomcat.util.buf.UDecoder
Klasse abgerufen wird, ist ihr Wert immer null
.
Wie könnte ich die Eigenschaft festlegen, bevor die org.apache.tomcat.util.buf.UDecoder
Klasse geladen wird?
Lösung
Beziehen Sie sich auf So legen Sie Umgebungsvariable oder Systemeigenschaft in Frühjahrstests fest?
Der einfachste Weg
Folgen Sie dem Hinzufügen eines statischen Initialisierers in der Klasse
...
class GlobalFullTest {
static {
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
}
...
}
down side is we need to copy that for every test.
Sauberer Weg
Erstellen Sie ApplicationContextInitializer , der in der Spring-Anwendung und jedem anderen Test wiederverwendet werden kann .
public class CustomApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>
{
@Override
public void initialize(ConfigurableApplicationContext applicationContext)
{
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
}
}
...
@ContextConfiguration(initializers = CustomApplicationContextInitializer.class,...)
class GlobalFullTest {
...
Beantwortet von – samabcde
Antwort geprüft von – Cary Denson (FixError Admin)