【问题标题】:Path variable read as a String rather than as a number Spring error路径变量读取为字符串而不是数字 Spring 错误
【发布时间】:2021-09-30 17:26:12
【问题描述】:

http://localhost:8080/basket/delete/%7BbasketId%7D?basketId=7&bookTitle=Ritle2&author=Rauther2&publisher=Publisher&quantity=1&price=5.0

上面的 URL 是在我的 Spring 应用程序中单击“从购物篮中删除项目”按钮时搜索的内容。控制器应该接收此篮子 ID(在本例中 = 7)并将其从篮子中删除。但是,我收到以下错误,因为它似乎是在“{basketId}”而不是 ID 本身中读取的:

[org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long'; nested exception is java.lang.NumberFormatException: For input string: "{basketId}"]

为什么会发生这种情况,我如何确保它接受了 basketId 的值?

HTML:

 <tr th:each="basketItem : ${basket}">
        <form action="/basket/delete/{basketId}" method="delete">
        <td> <input name="basketId"  th:value="${basketItem.basketId}"  readonly> </td>
        <td> <input name="bookTitle" th:value="${basketItem.bookTitle}"  readonly> </td>
        <td> <input name="author"    th:value="${basketItem.author}"   readonly> </td>
        <td> <input name="publisher" th:value="${basketItem.publisher}"readonly> </td>
        <td> <input name="quantity"  th:value="${basketItem.quantity}"   readonly> </td>
        <td> <input name="price"     th:value="${basketItem.price}"     readonly> </td>
            <td>  <button > Delete from basket</button></td>
        </form>
    </tr>

篮子控制器:

@DeleteMapping("/basket/delete/{basketId}")
 String deleteBook(@PathVariable  Long basketId, Model model) {
    System.out.println("Delte mapping : " + basketId);
    if (basketRepository.existsById(basketId)){
        basketRepository.deleteById(basketId);
    }
    else {
        System.out.println("Item does not exist!");
    };
    //basketRepository.save(basket);
    model.addAttribute("basket", basketRepository.findAll());
    return "basket/list";
}

@GetMapping("/basket/delete/{basketId}")
public String deleteItem(@PathVariable Long basketId,Model model) {
    System.out.println("Get mapping : " + basketId);
    Basket basketItem = basketRepository.findById(basketId)
            .orElseThrow();
    basketRepository.delete(basketItem);

    model.addAttribute("basket", basketRepository.findAll());

    return "basket/list";
}

篮子:

package springLibrary.domain;

import javax.persistence.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

@Entity
public class Basket {

 
    private @Id
    @GeneratedValue
    Long basketId;
    private String bookTitle;
    private String author;
    private String publisher;
    private int quantity;
    private double price;


    public Basket() {
    }

    public Basket(String bookTitle, String author, String publisher, int quantity, double price) {

        this.bookTitle = bookTitle;
        this.author = author;
        this.publisher = publisher;
        this.quantity = quantity;
        this.price = price;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Basket basket = (Basket) o;
        return Objects.equals(bookTitle, basket.bookTitle);
    }

    @Override
    public int hashCode() {
        return Objects.hash(bookTitle);
    }

    @Override
    public String toString() {
        return "Basket{" +
                "basketId=" + basketId +
                ", bookTitle='" + bookTitle + '\'' +
                ", author='" + author + '\'' +
                ", publisher='" + publisher + '\'' +
                ", quantity=" + quantity +
                ", price=" + price +
                '}';
    }

    public Long getBasketId() {
        return basketId;
    }

    public void setBasketId(Long basketId) {
        this.basketId = basketId;
    }

    public String getBookTitle() {
        return bookTitle;
    }

    public void setBookTitle(String bookTitle) {
        this.bookTitle = bookTitle;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getPublisher() {
        return publisher;
    }

    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

【问题讨论】:

  • 我对 Thymeleaf 不是很熟悉,但在你的操作中,它不应该是 ${basketId} 而不是 {basketId} 吗?毕竟你是在引用那个变量的值
  • 谢谢 Jetto,我刚刚尝试了美元符号/没有美元符号,不幸的是它仍然出现同样的错误
  • 错误的输出有变化吗?我得出这个结论是因为记录的错误是它试图将 {basketId} 解析为 Long。
  • 遗憾的是:
    2021-07-23 16:39:48.026 WARN 7996 --- [nio- 8080-exec-1] .wsmsDefaultHandlerExceptionResolver:已解决 [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException:无法将“java.lang.String”类型的值转换为所需的“java.lang.Long”类型;嵌套异常是 java.lang.NumberFormatException: For input string: "{basketId}"]
  • th:action 与适当的参数替换一起使用,否则将无法呈现正确的 URL。最后你会得到{baskedId},它(正如例外所告诉的那样)几乎不是一个数字。像th:action="@{/basket/delete/{basketId}(basketId=${basketItem.id})} 这样的东西,不确定语法是否完全正确,但类似这些。

标签: java html spring forms thymeleaf


【解决方案1】:

感谢@M。 Deinum 的原因 - 它被读取为字符串的原因是由于操作本身的格式。

在 Thymeleaf 中,它的结构应该是这样的:

<form th:action="@{/basket/delete/{basketId}(basketId=${basketItem.basketId})}" method="delete">

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-02
    • 2012-09-03
    • 1970-01-01
    • 2013-01-07
    • 1970-01-01
    • 2013-01-08
    • 1970-01-01
    • 2017-02-23
    相关资源
    最近更新 更多