【问题标题】:parameterizing object properties参数化对象属性
【发布时间】:2013-12-16 00:39:43
【问题描述】:

有人可以向我展示一种代码有效的方法,可以根据从超链接发送给它的参数来更改 spring mvc 中的对象属性吗?

我正在修改 spring petclinic 示例应用程序,以便“所有者”详细信息页面可以显示特定“所有者”拥有的每种“宠物”类型的单独列表。目前,“宠物”列表是每个“所有者”的属性,并且可以在 jstl 中作为 owner.pets 访问。我想要的是让我的 jstl 代码能够从 jstl 调用 owner.cats、owner.dogs、owner.lizards 等,并在网页的不同部分填充几个单独的列表,即使所有的猫、狗, 和蜥蜴存储在同一个基础数据表中。

我该如何做到这一点?

这里是JpaOwnerRepositoryImpl.java的相关方法:

@SuppressWarnings("unchecked")
public Collection<Owner> findByLastName(String lastName) {
    // using 'join fetch' because a single query should load both owners and pets
    // using 'left join fetch' because it might happen that an owner does not have pets yet
    Query query = this.em.createQuery("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName");
    query.setParameter("lastName", lastName + "%");
    return query.getResultList();
}

@Override
public Owner findById(int id) {
    // using 'join fetch' because a single query should load both owners and pets
    // using 'left join fetch' because it might happen that an owner does not have pets yet
    Query query = this.em.createQuery("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id");
    query.setParameter("id", id);
    return (Owner) query.getSingleResult();
}

这里是 Owner.java 的相关方面:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
private Set<Pet> pets;

protected Set<Pet> getPetsInternal() {
    if (this.pets == null) {this.pets = new HashSet<Pet>();}
    return this.pets;
}

public List<Pet> getPets() {
    List<Pet> sortedPets = new ArrayList<Pet>(getPetsInternal());
    PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true));
    return Collections.unmodifiableList(sortedPets);
}

这是 OwnerController.java 的一部分,它管理 url 模式“/owners”,我希望我的 jstl 能够从中单独列出页面的不同部分中的猫、狗、蜥蜴等(不是在一个分组中)列表,但在几个单独的列表中。):

@RequestMapping(value = "/owners", method = RequestMethod.GET)
public String processFindForm(@RequestParam("ownerID") String ownerId, Owner owner, BindingResult result, Map<String, Object> model) {
    Collection<Owner> results = this.clinicService.findOwnerByLastName("");
    model.put("selections", results);
    int ownrId = Integer.parseInt(ownerId);
    model.put("sel_owner",this.clinicService.findOwnerById(ownrId));
    return "owners/ownersList";
}

【问题讨论】:

  • 考虑在调试中运行应用程序,看看什么时候调用。如果您得到意外的输出,则可能是调用了错误的方法。

标签: java spring hibernate jpa


【解决方案1】:

由于您要求提供非冗长的解决方案,因此您可以只进行这种半脏的修复。

Owner.java

@Transient
private Set<Pet> cats = new HashSet<Pet>();

[...]

// Call this from OwnerController before returning data to page.
public void parsePets() {
  for (Pet pet : getPetsInternal()) {
    if ("cat".equals(pet.getType().getName())) {
      cats.add(pet);
    }
  }
}

public getCats() {
  return cats;
}

ownerDetail.jsp

[...]
<h3>Cats</h3>
<c:forEach var="cat" items="${owner.cats}">
    <p>Name: <c:out value="${cat.name}" /></p>
</c:forEach>

<h3>All pets</h3>
[...]

OwnerController.java

/**
 * Custom handler for displaying an owner.
 *
 * @param ownerId the ID of the owner to display
 * @return a ModelMap with the model attributes for the view
 */
@RequestMapping("/owners/{ownerId}")
public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) {
    ModelAndView mav = new ModelAndView("owners/ownerDetails");
    Owner owner = this.clinicService.findOwnerById(ownerId);
    owner.parsePets();
    mav.addObject(owner);
    return mav;
}

【讨论】:

  • 实际上,您正在对ClinicService 进行两次调用。不确定您是否在页面上使用第一次调用的结果。第二次调用由id 调用,因此返回一个Owner 对象,然后您将其保存到model 中以将其传输到JSP。那将是您从 JSTL 调用的对象,因此您想在该对象上调用 parsePets(),因此您已经填写了 catsdogs
  • 好像忘记了一些细节。您需要使用 @Transient 注释来处理不应保存到数据库的内容。与其他类型的解决方案合作过多,不需要这样做。
  • 既然你坚持,我就去本地电脑上找了宠物诊所,瞧,检查更新的答案。因此,它在我的本地设置上非常有效。您的应用程序是否出现某种错误?
  • 如果我以蒲公英数据表格式将其放在 ownerList.jsp 上并编辑 processFindForm 以返回单个选定的 Owner,则它的工作原理相同。您确实意识到,您不必像这样复制答案中的 JSTL(毕竟这只是一个简单的示例)? ${sel_owner.cats} 也可以使用数据表,一旦你将猫从宠物中解析出来。
  • 抱歉,延迟将此标记为答案。我最终没有将猫和狗设置为属性,而是创建了 getCats() 和 getDogs() 方法,它们各自创建了自己的内部列表并在方法结束时返回该列表。这使蒲公英表能够引用猫和狗,而不会因为创建对象属性或向属性添加注释而混淆。再次感谢您的所有努力。
猜你喜欢
  • 2017-08-08
  • 1970-01-01
  • 1970-01-01
  • 2016-04-09
  • 2020-08-25
  • 2012-02-01
  • 2013-02-12
  • 2022-01-17
  • 1970-01-01
相关资源
最近更新 更多