💡

Java | Spring Boot | Thymeleaf | in line Script

2025/02/11に公開

JavaのSpring Bootフレームワークで、Thymeleafテンプレート のin-Line-ScriptのJavaScript変数へJSONオブジェクトを埋め込む。

ObjectMapper:ListをJSONにエンコードしてクライアントへ渡す

  • ObjectMapperListJSONにエンコードしてクライアントへ渡す。
//Controller
List<ReviewHouseUserDTO> reviewList = reviewPage.getContent();
model.addAttribute("reviewList", reviewList);

ObjectMapper objectMapper = new ObjectMapper();
String reviewListJson = "[]";
try {
    reviewListJson = objectMapper.writeValueAsString(reviewList);
} catch (JsonProcessingException e) {
    e.printStackTrace();
}
model.addAttribute("reviewListJson", reviewListJson);
  • Thymeleaf<script th:inline="javascript"> (in line JavaScript)を使って、クライアント側でJSONを受け取る例。Thymeleafin line JavaScriptで変数にデータを入れて出力させる場合、var reviewData = /*[[${reviewListJson}]]*/ '[]';という独特の記法を用いて行う。
<script th:inline="javascript">
    /*<![CDATA[*/
    var reviewData = /*[[${reviewListJson}]]*/ '[]';
    /*]]>*/
</script>
<script>
    document.addEventListener("DOMContentLoaded", function() {
        // JSONデータをパース
        var parsedData = JSON.parse(reviewData);
        var container = document.getElementById("reviews-container");
        parsedData.forEach(function(reviewDTO) {
            var reviewElement = document.createElement("div");
            const formattedDate = formatDate(reviewDTO.review.updatedAt);
            var ratingStars = "☆☆☆☆☆";
            if(reviewDTO.review.rating == 1){
                ratingStars = "★☆☆☆☆";
            }else if(reviewDTO.review.rating == 2){
                ratingStars = "★★☆☆☆";
            }else if(reviewDTO.review.rating == 3){
                ratingStars = "★★★☆☆";
            }else if(reviewDTO.review.rating == 4){
                ratingStars = "★★★★☆";
            }else if(reviewDTO.review.rating == 5){
                ratingStars = "★★★★★";
            }
            reviewElement.className = "mb-3";
            reviewElement.innerHTML = `
                <a href="/houses/${reviewDTO.house.id}" class="link-dark honyahonyalalalaravel-card-link">
                    <div class="card h-100">
                        <div class="row g-0">
                            <!-- 画像の表示部分 -->
                        </div>
                        <div class="col-md-12">
                            <div class="card-body">
                                <h3 class="card-title mb-3">${reviewDTO.house.name}</h3>
                                <h5>${formattedDate}</h5>
                                <h5>${ratingStars}</h5>
                                <h5>${reviewDTO.review.reviewText}</h5>
                                <p>${reviewDTO.user.name}</p>
                            </div>
                        </div>
                    </div>
                </a>
            `;
            container.appendChild(reviewElement);
        });
    });
    function formatDate(dateString) {
        const date = new Date(dateString);
        const year = date.getFullYear();
        const month = date.getMonth() + 1; // 月は0から始まるので+1
        const day = date.getDate();
        return `${year}/${month}/${day}`;
    }
</script>

Discussion