Dziwny problem z delete spring boot 2

Dziwny problem z delete spring boot 2
ST
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 75
0

Witam, mam dziwny problem, Na szybko - projekt spring boot 2 thymeleafem generuje

Kopiuj
<div th:each="link : ${links}">
        <div class="card text-center">
        <span th:text="${link.getId()}"></span>
. . .
<form th:method="DELETE" th:action="@{'/link/' + ${link.getId()}}" id="formDelete"></form>

np. mam 10 wpisow czyli id od 1 do 9 (w span dla testu dałem getId żeby zobaczyć czy poprawne id i wszystko jest ok) czyli oczekuje że klikne delete tego z np id 6 to usunie id 6.

kontroller

Kopiuj
@DeleteMapping("/link/{id}")
public String deleteLink(@PathVariable Long id) {
        System.out.println("delete mapping " + id);

i tu magia. Klikam link z ID 6 a w kontrolerze pokazuje że kliknąłem ID 1, potem klikam np ID 4 a w kontrolerze pokazuje że kliknąłem ID 2 itd... czyli rosnąco ale nie te ID które klikam

Gdzie mam zacząć szukać błędu? bo już zgłupiałem

ST
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 75
0

Rozwiązałem to mapowaniem Get i linkiem

Kopiuj
<a th:href="@{'/link/' + ${link.getId()} + '/delete'}" target="">delete get</a>

Ale czy to jest dobre rozwiązanie dla usuwania wpisów z bazy danych?

Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Space: the final frontier
  • Postów: 26433
5

Nie. Robienie czegokolwiek (edit: czegokolwiek co modyfikuje stan ofc) GETem to dramat.

  1. GET może w ogóle nie wyjść z przeglądarki, bo cache. Przeglądarka uzna że strona się nie zmieniła i nie wyśle requestu tylko wczyta sobie wynik z cache. Zresztą są też cache na innym poziomie jak jakiś CloudFlare, więc jeszcze gorzej.
  2. GET może wyjść z przeglądarki nawet jak nie chcesz, bo przeglądarka robi sobie prefetch linków. Ty tylko załadowałeś stronę z listą linków a przeglądarka już je wszystkie odpaliła i wszystko skasowała :D
  3. GET nie jest chroniony przez CSRF więc ktoś może ci wszystko pokasować za pomocą skryptu JS na zupełnie innej stronie. Po prostu ten skrypt będzie wysyłał ajaxem GET na ten twój endpoint /delete. Wysyłam ci linka do mojej strony ze śmiesznymi kotami a w międzyczasie kasuje ci wszystko.

Ad pytania z pierwszego posta, może te linki masz w jakimś HashSecie albo innej strukturze bez kolejności a generujesz to na stronie osobnymi pętlami i kolejność może się zmienić? Trudno powiedzieć nie widząc szablonu ani kontrolera.

ST
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 75
0

wiec dokladniej, to działa:

Kopiuj
@GetMapping("/link/{id}/delete")
    public String deleteLink2(@PathVariable Long id, RedirectAttributes redirectAttributes) {

        System.out.println("delete mapping " + id);

                linkService.deleteById(id);

        return "redirect:/";
    }

a to **NIE **działa:

Kopiuj
@DeleteMapping("/link/{id}")
    public String deleteLink(@PathVariable Long id) {

        System.out.println("delete mapping " + id);

                linkService.deleteById(id);
          
        return "redirect:/";
    }

a tu widok z wersją GET:

Kopiuj
<div th:each="link : ${links}">

<a class="text-danger" th:href="@{'/link/' + ${link.getId()} + '/delete'}" target="" style="text-decoration:none"><i class="far fa-trash-alt"></i></a>

 </div>

i z delete

Kopiuj
<div th:each="link : ${links}">

<form th:action="@{'/link/' + ${link.getId()}}" th:method="delete" >
<input type="hidden" name="_method" value="delete" />
<button type="submit" id="submitButton"> delete </button>
</form>

 </div>
Belka
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: PL
  • Postów: 452
0
Shalom napisał(a):

Nie. Robienie czegokolwiek GETem to dramat.

Czyli jak robić pobieranie czegoś z backendu na front w celu wyświetlenia? Chyba, że chodziło Ci o operacje, które mają jakiś wpływ na stan encji w bazie danych.

Pytam, bo nie za bardzo czaję o co Ci chodzi i jakie są alternatywy, a nie ukrywam że zaintrygowało mnie Twoje twierdzenie.

baant
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 524
0

Alternatywa to np. POST :) A do usuwania czegoś to można i nawet awangardowo DELETE walnąć

Belka
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: PL
  • Postów: 452
0
baant napisał(a):

Alternatywa to np. POST :) A do usuwania czegoś to można i nawet awangardowo DELETE walnąć

Czyli dane też pobierać postem? A jak wtedy rozwiązać kwestię ewentualnych @PathVariable?

S9
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Warszawa
  • Postów: 3573
0

Czyli jak robić pobieranie czegoś z backendu na front w celu wyświetlenia? Chyba, że chodziło Ci o operacje, które mają jakiś wpływ na stan encji w bazie danych.

Dokładnie chodziło o modyfikację stanu, nie musze być to encje w bazie danych...

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.