Java 列表项在页面重新加载时重新添加到 thymeleaf 下拉列表中,多次出现

Posted

技术标签:

【中文标题】Java 列表项在页面重新加载时重新添加到 thymeleaf 下拉列表中,多次出现【英文标题】:Java list items re-added to thymeleaf dropdown on page reload, appearing multiple times 【发布时间】:2019-11-09 13:30:24 【问题描述】:

我正在构建一个 Spring Boot 应用程序,该应用程序每月计算和显示 Airbnb 付款。支付数据从 Airbnb Api 中提取,用户帐户信息存储在数据库中。 我创建了一个表单,用户可以在其中指定月份和列表以显示每月支出。用户从下拉菜单中选择列表(租赁)。为了显示列表的名称,一个listingListDto 属性被添加到MVC 模型中。从数据库中获取列表实体列表,并将其转换为列表 DTO 实体列表。这个列表给出了listingListDto。

当我重新加载表单页面时,列表会被读取到下拉列表中,出现两次,然后出现三、四次甚至更多次。

我怎样才能防止这种情况发生? 我假设我可以创建一个ListingListDTO 实体,它会包装ListingDTOs,但我希望能够保持简单,并直接在MVC 模型中使用ListingDTOs。

这是显示 html 表单的 Controller 方法:

    @RequestMapping(value = "payout", method = RequestMethod.GET)
    public String payoutSelection(Model model, RedirectAttributes redirectAttributes) 
        Long userId = sessionService.getCurrentUserId();
        if (null == userId) 
            return loginService.handleInvalidLogin("payout", redirectAttributes);
         else 
            PayoutSelectionDTO payoutSelectionDto = new PayoutSelectionDTO();
            LocalDate lastMonth = LocalDate.now().minusMonths(1);
            payoutSelectionDto.setYear(lastMonth.getYear());
            payoutSelectionDto.setMonth(lastMonth.getMonthValue());

            Optional<User> user = userService.getUserById(userId);
            model.addAttribute("payoutSelectionDto", payoutSelectionDto);
            model.addAttribute("listingListDto", listingListDtoService.getListingListDTO(listingService.getListingsByUser(user.get())));
            return "payout_monthpicker.html";
        
       

这是包含列表下拉列表的表单:

<body>
    <div class="content-block">
        <form action="#" th:action="@/get_payouts"
            th:object="$payoutSelectionDto" method="POST">
            <h2>Kifizetések lekérése</h2>
            <div class="content-group">
                <select th:field="*year">
                    <option th:value="$payoutSelectionDto.year -1"
                        th:text="$payoutSelectionDto.year -1"></option>
                    <option th:value="*year" th:text="*year"></option>
                </select> <select th:field="*month">
                    <option th:value="'1'" th:text="Január"></option>
                    <option th:value="'2'" th:text="Február"></option>
                    <option th:value="'3'" th:text="Március"></option>
                    <option th:value="'4'" th:text="Április"></option>
                    <option th:value="'5'" th:text="Május"></option>
                    <option th:value="'6'" th:text="Június"></option>
                    <option th:value="'7'" th:text="Július"></option>
                    <option th:value="'8'" th:text="Augusztus"></option>
                    <option th:value="'9'" th:text="Szeptember"></option>
                    <option th:value="'10'" th:text="Október"></option>
                    <option th:value="'11'" th:text="November"></option>
                    <option th:value="'12'" th:text="December"></option>

                </select>
            </div>
            <div class="content-group">
                <select th:field="*listingId">
                    <option th:each="listingDto : $listingListDto" th:value="$listingDto.airbnbId" th:text="$#strings.abbreviate(listingDto.airbnbLabel,30)"></option>    
                </select>
            </div>

            <div class="content-group">
                <button type="submit" class="btn btn-primary btn-lg btn-block">Lekérés indítása</button>
            </div>
        </form>
    </div>
</body>

这是ListingListDtoService。它有一种筛选重复项的方法,因此除非这不是我认为的那样,否则运行此服务的结果不应该存在重复项。


@Service
public class ListingListDTOService 
    List<ListingDTO> listingDtoList;

    public ListingListDTOService() 
        this.listingDtoList = new ArrayList<>();
    

    public List<ListingDTO> getListingListDTO(List<Listing> listingList) 
        for(Listing listing : listingList) 
            ListingDTO listingDto = convertListingToListingDTO(listing);
            if(!listingDtoList.contains(listingDto)) 
                listingDtoList.add(listingDto);
            
            else 
                System.out.println("identical Dto found in list while adding Dtos.");
            

        
        return listingDtoList;
    
    public ListingDTO convertListingToListingDTO(Listing listing) 
        ListingDTO listingDto = new ListingDTO();
        listingDto.setAirbnbId(listing.getAirbnbId());
        listingDto.setAirbnbLabel(listing.getAirbnbLabel());
        listingDto.setAirbnbPictureUrl(listing.getAirbnbPictureUrl());
        return listingDto ;
    


感谢@Seth 的评论,这个问题已经解决了。

【问题讨论】:

我认为查看ListingListDtoService 的代码会有所帮助,因为您在此服务的结果中看到了您的问题,对吗? 感谢 KevinB 的评论。我已经添加了 ListingListDtoService。 如果您在ListingDTO 上没有好的equals()/hashcode() 方法,那么您的contains() 调用将无法满足您的要求。 谢谢@Seth。我已经实现了 equals()/hashcode() 方法,现在可以正常工作了。 【参考方案1】:

只是抄袭cmets来回答这个问题。

如果您在 ListingDTO 上没有好的 equals()/hashcode() 方法,那么您的 contains() 调用将无法执行您想要的操作。

【讨论】:

以上是关于Java 列表项在页面重新加载时重新添加到 thymeleaf 下拉列表中,多次出现的主要内容,如果未能解决你的问题,请参考以下文章

重新加载具有相同内容的 div

Laravel - 创建一个会话数组并在每次重新加载页面时添加到它

页面位于 iFrame 中时未保存会话变量

重新加载后设置 jplist-drop-down 的值

添加到浏览器历史记录而无需重新加载页面

如何在颤动中从列表中删除项目时重新加载列表