Tive o seguinte erro após habilitar o processamento assíncrono no controlador. OBS: Sem o retorno Callable funciona normalmente!
HTTP Status 500 - Request processing failed; nested exception is java.lang.IllegalStateException: Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "true" to servlet and filter declarations in web.xml.
Seguem os códigos fonte.
PagamentoController.java
package br.com.gbd.alura.controllers;
import br.com.gbd.alura.models.DadosPagamento;
import br.com.gbd.alura.models.CarrinhoCompras;
import br.com.gbd.alura.models.TipoPreco;
import java.util.concurrent.Callable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
/*
Autor(es): José Carlos de Freitas
Data: 23/03/2017 às 15:48:16
Arquivo: PagamentoController
*/
@Controller
@RequestMapping("/pagamento")
public class PagamentoController {
@Autowired
CarrinhoCompras carrinho;
@Autowired
RestTemplate restTemplate;
@RequestMapping(value = "/finalizar", method = RequestMethod.POST)
public Callable<ModelAndView> finalizar(RedirectAttributes redirectAttributes) {
return () -> {
try {
String url = "http://book-payment.herokuapp.com/payment";
String response = restTemplate.postForObject(url, new DadosPagamento(carrinho.getTotal()), String.class);
System.out.println(carrinho.getTotal());
redirectAttributes.addFlashAttribute("msg", response);
return new ModelAndView("redirect:/produtos");
} catch (HttpClientErrorException e) {
e.printStackTrace();
redirectAttributes.addFlashAttribute("msg", "Valor maior que o permitido");
return new ModelAndView("redirect:/produtos");
}
};
}
@RequestMapping("/remover")
public ModelAndView remover(Integer produtoId, TipoPreco tipoPreco) {
carrinho.remover(produtoId, tipoPreco);
return new ModelAndView("redirect:/carrinho");
}
}
AppWebConfiguration.java
package br.com.gbd.alura.conf;
import br.com.gbd.alura.controllers.HomeController;
import br.com.gbd.alura.daos.ProdutoDAO;
import br.com.gbd.alura.infra.FileSaver;
import br.com.gbd.alura.models.CarrinhoCompras;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.format.datetime.DateFormatter;
import org.springframework.format.datetime.DateFormatterRegistrar;
import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
/*
Autor(es): José Carlos de Freitas
Data: 05/03/2017 às 10:33:53
Arquivo: AppWebConfiguration
*/
@EnableWebMvc
@ComponentScan(basePackageClasses = {HomeController.class, ProdutoDAO.class, FileSaver.class, CarrinhoCompras.class})
class AppWebConfiguration extends WebMvcConfigurerAdapter {
@Bean
public InternalResourceViewResolver internalResourceViewResolve() {
InternalResourceViewResolver resolve = new InternalResourceViewResolver();
resolve.setPrefix("/WEB-INF/jsp/");
resolve.setSuffix(".jsp");
resolve.setExposedContextBeanNames("carrinhoCompras");
return resolve;
}
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource
= new ReloadableResourceBundleMessageSource();
messageSource.setBasename("/WEB-INF/messages");
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(1);
return messageSource;
}
@Bean
public FormattingConversionService mvcConversionService() {
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
DateFormatterRegistrar registra = new DateFormatterRegistrar();
registra.setFormatter(new DateFormatter("dd/MM/yyyy"));
registra.registerFormatters(conversionService);
return conversionService;
}
@Bean
public MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
Creio que seja um problema de configuração, como o próprio erro descreve, mas não pesquisei muito sobre.