Je crée un service SOAP qui devrait être exécuté sur Tomcat.
J'utilise Spring Boot pour mon application, similaire à:
@Configuration
@EnableAutoConfiguration(exclude = ErrorMvcAutoConfiguration.class)
public class AppConfig {
}
Mon service Web (exemple):
@Component
@WebService
public class MyWebservice {
@WebMethod
@WebResult
public String test() {
throw new MyException();
}
}
@WebFault
public class MyException extends Exception {
}
Problème:
Chaque fois que je lève une exception dans la classe webservice, le message suivant est enregistré sur le serveur:
ErrorPageFilter: impossible de transférer vers la page d'erreur pour la demande [/ services/MyWebservice] car la réponse a déjà été validée. En conséquence, la réponse peut avoir le mauvais code d'état. Si votre application s'exécute sur WebSphere Application Server, vous pourrez peut-être résoudre ce problème en définissant com.ibm.ws.webcontainer.invokeFlushAfterService sur false
Question:
Comment puis-je éviter cela?
Pour désactiver le ErrorPageFilter
dans Spring Boot (testé avec 1.3.0.RELEASE), ajoutez les beans suivants à votre configuration Spring:
@Bean
public ErrorPageFilter errorPageFilter() {
return new ErrorPageFilter();
}
@Bean
public FilterRegistrationBean disableSpringBootErrorFilter(ErrorPageFilter filter) {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(filter);
filterRegistrationBean.setEnabled(false);
return filterRegistrationBean;
}
La façon la plus simple de désactiver ErrorPageFilter est:
@SpringBootApplication
public class App extends SpringBootServletInitializer {
public App() {
super();
setRegisterErrorPageFilter(false); // <- this one
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(App.class);
}
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
//set register error pagefilter false
setRegisterErrorPageFilter(false);
builder.sources(MyApplication.class);
return builder;
}
}
J'ai trouvé dans les sources que le ErrorPageFilter.Java
a le code suivant:
private void doFilter(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws IOException, ServletException {
ErrorWrapperResponse wrapped = new ErrorWrapperResponse(response);
try {
chain.doFilter(request, wrapped);
int status = wrapped.getStatus();
if (status >= 400) {
handleErrorStatus(request, response, status, wrapped.getMessage());
response.flushBuffer();
}
else if (!request.isAsyncStarted() && !response.isCommitted()) {
response.flushBuffer();
}
}
catch (Throwable ex) {
handleException(request, response, wrapped, ex);
response.flushBuffer();
}
}
Comme vous pouvez le voir lorsque vous lâchez une exception et renvoyez un code de réponse> = 400, cela fera du code. il devrait y avoir une vérification supplémentaire si la réponse a déjà été validée ou non.
La façon de supprimer ErrorPageFilter est la suivante
protected WebApplicationContext run(SpringApplication application) {
application.getSources().remove(ErrorPageFilter.class);
return super.run(application);
}
Chris
La meilleure façon consiste à dire au conteneur WebSphere d'arrêter ErrorPageFiltering. Pour ce faire, nous devons définir une propriété dans le fichier server.xml.
<webContainer throwExceptionWhenUnableToCompleteOrDispatch="false" invokeFlushAfterService="false"></webContainer>
Alternativement, vous pouvez également le désactiver dans le fichier spring application.properties
logging.level.org.springframework.boot.context.web.ErrorPageFilter=off
Je préfère la première façon, j'espère que cela aide.