胸腺th:每个都找不到对象

时间:2019-02-12 09:39:49

标签: spring-boot spring-mvc thymeleaf

我在Springboot 2.1.2中使用Thymeleaf,并且Thymeleaf的th:each标签有问题。 这是我的代码:

    <tr th:each="addr : ${user.addressList}">
        <td><input type="text" th:value="${addr.name}" th:field="${addr.name}"></td>
        <td><input type="text" th:value="${addr.phone}" th:field="${addr.phone}"></td>
        <td><input type="text" th:value="${addr.location}" th:field="${addr.location}"></td>
        <td><a th:href="@{/user/addr/del/{id}(id=${addr.id})}">del</a></td>
    </tr>

但是,我遇到以下异常:

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'addr' available as request attribute

调试器说找不到变量,但是,我确定视图有一个名为“ user”的绑定对象,因为我在前面的其他地方使用了它。

这是我的控制者和我的实体:

@GetMapping("/profile")
public String getProfile(HttpServletRequest request, Model model) {
    HttpSession session = request.getSession(false);
    String email = (String) session.getAttribute("userId");
    User user = userService.getProfile(email);
    model.addAttribute("user", user);
    return "user/profile";
}

@Entity
public class User {

    @Id
    private String email;
    private String userName, password;
    private int pts;    //积分
    private int status= Flags.USER_EXIST;

    @OneToMany(targetEntity = Address.class
        , fetch = FetchType.LAZY, mappedBy = "user"
        , cascade = {CascadeType.PERSIST,CascadeType.REMOVE})
    private List<Address> addressList = new ArrayList<>();

    //constructors and getters and setters below...
}

@Entity
public class Address {
    @Id
    @GeneratedValue //去掉这个注解会导致一系列bug
    private long id;
    private String name, phone, location;
    @ManyToOne(targetEntity = User.class)
    private User user;

    //constructors and getters and setters below...
}

我按照教程here进行操作,每次使用与本教程之间都找不到任何区别。你能帮我吗?

更新=========================================== < / p>

这是我的UserService.getProfile(字符串电子邮件)代码:

@Override
public User getProfile(String email) {
    Optional<User> res = userRepository.findById(email);
    return res.isPresent() ? res.get() : null;
}

再次更新============================================= ============>

总结我到目前为止所做的事情:

1)在User类中使用FetchType.EAGER

2)通过打印addressList强制存储库检索相关的地址:

user.getAddressList().stream().forEach(x -> System.out.println(x.getLocation()));

3)删除th:each块并重新启动我的应用程序,没有例外;当我重新添加块时,我的应用再次失败...

所有这些措施似乎都没有帮助我。...

3 个答案:

答案 0 :(得分:0)

问题毕竟与JPA不相关。问题是您如何使用th:field。请参阅有关正确用法的文档:https://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#dynamic-fields

尝试一下:

<tr th:each="addr,addrStat : ${user.addressList}">
        <td><input type="text" th:value="${addr.name}" th:field="*{addressList[__${addrStat.index}__].name}"></td>

...         

答案 1 :(得分:0)

您遇到此错误:-

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'addr' available as request attribute

因为您在控制器上使用 @ModelAttribute 注释。
您正在尝试在提交后将名为addr的对象发送到控制器,但是您并没有从您所在的控制器向控制器发送确切名称为addr的对象。重新打开您请求的html页面。

这是一个使用 @ModelAttribute 注释发送对象的快速示例:-

1。)您从打开请求的HTML页面的位置所请求的控制器将是这样的:-

@RequestMapping("/test")
    public String test(HttpServletRequest request,Model model){

    //your code
  model.addAttribute("addr",new MyTest());
  return "yourRequestedPage";
  }

2。)提交后,您的下一个控制器将是这样的:-

@RequestMapping("/testAfterSubmit")
    public String someMethodName(@ModelAttribute("addr") MyTest myTestClass,HttpServletRequest request,Model model ) {
//your code . . 

 }

PS -有关@ModelAttribute的用途的更多信息,这是快速参考:-

What is @ModelAttribute in Spring MVC?

答案 2 :(得分:0)

我以为我已经找到了问题...这非常棘手...我编辑了th:each块,现在就像:

    <tr th:each="addr : ${user.addressList}">
        <td><input type="text" th:value="${addr.name}"></td>
        <td><input type="text" th:value="${addr.phone}"></td>
        <td><input type="text" th:value="${addr.location}"></td>
        <td><a th:href="@{/user/addr/del/{id}(id=${addr.id})}">del</a></td>
    </tr> 

您找到了区别吗?是的,我删除了th:field标签!在原始代码中,我所做的是将列表中的Address对象的属性绑定到迭代器!我想可能是只读的,所以编译器会在模型中期望一个名为“ addr”的对象,当然这会失败...

此错误警告我将修改功能和演示功能分离到各自的视图中...