【问题标题】:Exception when I try use get mapping in Spring Boot and MVC当我尝试在 Spring Boot 和 MVC 中使用获取映射时出现异常
【发布时间】:2019-05-02 10:17:10
【问题描述】:

我有一个简单的 getmapping:

@GetMapping(value = "{user}")
    public String edit(@PathVariable User user, Model model) {
        model.addAttribute("user", user);
        return "userEdit";
    }

在我看来,我只提供实体 ID:

<tr>
   <td>${user.name}</td>
   <td><a href="/user/${user.id}">Edit</a></td>
</tr>

最后在我的数据库中我有这个实体:

@Entity
@Table(name = "users")
public class User implements UserDetails {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

}

但是当我尝试使用我的控制器时,我得到了这个异常:

出现意外错误(类型=错误请求,状态=400)。失败的 将“java.lang.String”类型的值转换为所需类型 'com.newtwitter.model.User';嵌套异常是 org.springframework.core.convert.ConversionFailedException: 失败 从类型 [java.lang.String] 转换为类型 [@org.springframework.web.bind.annotation.PathVariable com.newtwitter.model.User] 为值 '1';嵌套异常是 org.springframework.dao.InvalidDataAccessApiUsageException:提供 com.newtwitter.model.User 类的错误类型的 ID。预期的: 类 java.lang.Long,得到类 java.lang.Integer;嵌套异常是 java.lang.IllegalArgumentException:为 com.newtwitter.model.User 类。预期:类 java.lang.Long,得到 类 java.lang.Integer

我可以修复它吗?

【问题讨论】:

  • 您无法将用户值读取为路径变量中的“用户”类型。尝试将类型更改为 String 或 long
  • 您可以将用户 ID 放在路径变量上,而不是整个 User 对象上。
  • 如果启用了 Spring Data Web 扩展,您可以指定一个用户实例,如我的回答中所述。
  • 你可以使用 Converter 将用户 id 转换为用户对象,或者从路径变量中获取 id,然后从数据库中获取用户

标签: java spring-mvc spring-boot jpa spring-data


【解决方案1】:

您在控制器中接受用户对象,但从前端发送一个 id,因此发生此错误,因此您可以将方法更改为如下所示。

@GetMapping(value = "{id}")
    public String edit(@PathVariable Long id, Model model) {
        User user = userService.read(id); //read user from the DB by id
        model.addAttribute("user", user);
        return "userEdit";
 }

更新:

否则您应该按照下面的方法使用包含完整更新对象的模型属性来更新用户,您只需将其直接保存到数据库。

@RequestMapping(method = RequestMethod.PUT, produces = "text/html")
    public String update(User user, BindingResult bindingResult, Model uiModel,
            HttpServletRequest httpServletRequest)
    {
        //update user
        uiModel.addAttribute("user", user);
        return "updatedSuccess.jsp";
    }

【讨论】:

  • 是的,我可以做到,但方法很简单。我知道 Spring 可以为我做到这一点。我想知道我想念哪里。
【解决方案2】:

本质上,您的控制器方法将用户对象作为参数,但框架有一个字符串,并且不能将其转换为用户的实例。

您的代码支持,但是您需要使用 Spring 数据(您可能是)并启用 Spring Data MVC 扩展才能自动进行此转换。 p>

这在手册中有记录(4.8.2. Web 支持):

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#core.web

其中指出将@EnableSpringDataWebSupport 添加到您的配置中:

注册一些基本组件:

[包括]

一个 DomainClassConverter 让 Spring MVC 解析 来自请求参数或路径的存储库管理的域类 变量。

如果没有 Spring Data Web 扩展,您需要将方法签名更改为以下内容并手动查找实例。

@GetMapping(value = "{user}")
    public String edit(@PathVariable Long userId, Model model) {
        User user = //user userId to fetch
        model.addAttribute("user", user);
        return "userEdit";
}

【讨论】:

    【解决方案3】:
    @GetMapping(value = "{user}")
    

    将值更改为字符串,您不能将对象传递给端点。

    public String edit(@PathVariable User user, Model model) {
            model.addAttribute("user", user);
            return "userEdit";
        }
    

    将@PathVariable 更改为@RequestBody,这样您就可以将用户作为对象访问。或者您可以如下更改:

    @GetMapping(value = "user/{id}")
        public String edit(@PathVariable String id, Model model) {
    // you can get user information base on id here
            model.addAttribute("user", user);
            return "userEdit";
        }
    

    【讨论】:

      猜你喜欢
      • 2020-07-20
      • 1970-01-01
      • 2021-05-06
      • 1970-01-01
      • 2020-11-11
      • 1970-01-01
      • 2019-09-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多