Issue
There is an Exception that is thrown when an user is not found in database and i'd like to handle that particular exception from the controller perspective layer in a separated method by @ExceptionHandler annotation without losing the original data sent by the user. Well, so, i'm using Sessions and my first attempt was trying to get the object back from it by HttpServletRequest but i got:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'pontoEditar' available as request attribute
The code:
@ExceptionHandler(ConversionFailException.class)
public String handleConversionFailException(HttpServletRequest request, RedirectAttributes attr) {
PontoEditarDTO ponto = (PontoEditarDTO) request.getAttribute("pontoEditar");
// I'd like to get the original object back ...
return "pontos/editar";
}
How would it be if i use a try-catch block
@PostMapping
public String editar(@ModelAttribute("pontoEditar") PontoEditarDTO ponto, HttpSession session) {
// ... simplified.
Ponto pontoConvertido = null;
try {
pontoConvertido = pontoConverter.convert(ponto);
catch (ConversionFailException ex) {
attr.addFlashAttribute("error", "User not found!");
return "redirect:/ponto/listar";
}
// ...
return "redirect:/ponto/listar";
}
Here the simplified code:
public class ConversionFailException extends RuntimeException {
public ConversionFailException(String mensagem) {
super(mensagem);
}
}
- Controller with POST.
The exception happens in the POST at line with: Ponto pontoConvertido = pontoConverter.convert(ponto);
@Controller
@SessionAttributes("pontoEditar")
@RequestMapping("/ponto/editar")
public class PontoEditarController {
// ... GET Removed.
@PostMapping
public String editar(@ModelAttribute("pontoEditar") PontoEditarDTO ponto, HttpSession session) {
// ... simplified.
Ponto pontoConvertido = pontoConverter.convert(ponto);
// ...
return "redirect:/ponto/listar";
}
@ExceptionHandler(ConversionFailException.class)
public String handleConversionFailException(HttpServletRequest request, RedirectAttributes attr) {
attr.addFlashAttribute("falha", "Usuário não foi encontrado");
/* I tried but it failed, how can i get ? */
PontoEditarDTO ponto = (PontoEditarDTO) request.getAttribute("pontoEditar");
return "pontos/editar";
}
@GetMapping("pontoEditar")
public PontoEditarDTO getPontoModel() {
return new PontoEditarDTO();
}
}
Solution
You can add WebRequest
(or HttpSession, etc...) as a parameter in your exception handler, it will be injected by Spring.
You can have a look at the documentation here to see what parameter can be injected by Spring when the handler is called.
Answered By - Cyril G.
Answer Checked By - Clifford M. (JavaFixing Volunteer)