Error in request Delete in Spring: console indicates that method is not supported

2

I am making a request via Ajax to delete a user and I get the message that the delete method is not supported, does anyone have any idea what it could be?

My controller:

package com.br.livraria.controller;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.br.livraria.controller.page.PageWarapper;
import com.br.livraria.model.Usuario;
import com.br.livraria.repository.Usuarios;
import com.br.livraria.repository.filter.UsuariosFilter;
import com.br.livraria.service.CadastroUsuarioService;
import com.br.livraria.service.exception.ImpossivelExcluirEntidadeException;
import com.br.livraria.service.exception.SenhaObrigatoriaException;
import com.br.livraria.service.exception.UsuarioJaCadastradoException;

@Controller
@RequestMapping("usuario")
public class UsuariosController {

    @Autowired
    private CadastroUsuarioService usuarioService;

    @Autowired
    private Usuarios usuarios;

    @GetMapping("/novo")
    public ModelAndView novo(Usuario usuario){
        ModelAndView mv = new ModelAndView("usuario/cadastro-usuario");

        return mv;
    }

    @GetMapping
    public ModelAndView pesquisaUsuarios(UsuariosFilter usuariosFilter, Pageable pageable, 
                                                BindingResult result, HttpServletRequest httpServletRequest){

        ModelAndView mv = new ModelAndView("usuario/pesquisa-usuario");

        PageWarapper<Usuario> pagina = new PageWarapper<>(usuarios.filtrar(usuariosFilter, pageable), httpServletRequest);
        mv.addObject("pagina", pagina);

        return mv;
    }

    @GetMapping("/{codigo}")
    public ModelAndView buscarUsuario(@PathVariable Long codigo){
        Usuario usuario = usuarios.findByCodigo(codigo);
        ModelAndView mv = novo(usuario);
        mv.addObject(usuario);
        return mv;
    }

    @PostMapping(value = { "/novo" , "{\+d}"})
    public ModelAndView salvar(@Valid Usuario usuario, BindingResult result, RedirectAttributes attributes){
        if(result.hasErrors()){
            return novo(usuario);
        }

        try {
            usuarioService.salvar(usuario);
        } catch (UsuarioJaCadastradoException e) {
            result.rejectValue("email", e.getMessage(), e.getMessage());
            return novo(usuario);
        } catch (SenhaObrigatoriaException e) {
            result.rejectValue("senha", e.getMessage(), e.getMessage());
            return novo(usuario);
        }

        attributes.addFlashAttribute("mensagem", "Usuário salvo com sucesso!");

        return new ModelAndView("redirect:/usuario/novo");
    }

    @DeleteMapping("/{codigo}")
    public @ResponseBody ResponseEntity<?> excluir(@PathVariable Long codigo){
        try {
            usuarioService.excluir(codigo);
        } catch (ImpossivelExcluirEntidadeException e) {
            return ResponseEntity.badRequest().body(e.getMessage());
        }

        return ResponseEntity.ok().build();
    }
}

Excerpt from the Ajax request:

   function onExcluirConfirmado(url) {
        $.ajax({
            url: url,
            method: "DELETE",
            success: onExcluidoSucesso.bind(this),
            error: onErrorExcluir.bind(this),
        });
    }

    function onExcluidoSucesso() {
        var urlAtual = window.location.href;
        var separador = urlAtual.indexOf('?') > -1 ? '&' : '?';
        var novaUrl = urlAtual.indexOf('excluido') > -1 ? urlAtual : urlAtual + separador + 'excluido';
        window.location = novaUrl;
    }

    function onErrorExcluir(e){
        swal('Oops!', e.responseText, 'error');
    }
    
asked by anonymous 25.10.2017 / 14:53

2 answers

1

Friends, I managed to find the solution. As I'm using Spring Segurity, it is essential to send the _csrf tokens on all ajax requests, I made the _csrf tokens available in my default layout to replicate them to the entire application, and added the following to my main javascript:

Livraria.Security = (function() {

	function Security() {
		this.token = $('input[name=_csrf]').val();
		this.header = $('input[name=_csrf_header]').val();
	}
	
	Security.prototype.iniciar = function() {
		//toda vez que é enviado uma requisição em ajax
		$(document).ajaxSend(function(event, jqxhr, settings) {
			jqxhr.setRequestHeader(this.header, this.token);
		}.bind(this));
	}

$(function() {
		
	var security = new Livraria.Security();
	security.iniciar();
}());
    
26.10.2017 / 01:43
0

Opa,

In your ajax, change from:

url: url,
method: "DELETE",

To:

url: url,
type: 'DELETE',
contentType : 'application/json

And in the controller, add:

@DeleteMapping("/{codigo}", consumes = { MediaType.APPLICATION_JSON_VALUE })
    
25.10.2017 / 17:31