[英]spring boot thymleaf resources are not working for all pages
我是themleaf模板引擎的新手。 我有一個使用他們mleaf 模板引擎的spring boot web 應用程序。 下面是我的項目結構。
我有home.html
,我在其中調用了 header(在header.html
)和頁腳(在footer.html
)片段,對於內容部分,我調用了另一個片段,即 familytree(在familytree.html
)和所有內容到目前為止工作正常。 當我運行 spring boot 應用程序時,我得到了預期的視圖。
問題:現在我創建了另一個名為viewfulltree.html
html 頁面(復制home.html
頁面並粘貼到同一目錄中,並將其重命名為viewfulltree.html
以確保每件事都像home.html
工作)。 這個viewfulltree.html
只是home.html
另一個副本,具有不同的名稱。 現在,當我從我的控制器類返回這個viewfulltree.html
頁面時,它無法找到css,js,images
文件,因此視圖被弄亂了,沒有樣式,沒有動作,沒有圖像。 我不確定我在配置中犯了什么錯誤。 由於兩者都在同一目錄中並使用相同的header.html
片段,所以我希望兩者都應該能夠以相同的方式訪問靜態內容。
控制器類::
@Controller
public class DefaultController {
@GetMapping("/")
public String defaultHome(){
return "redirect:home";
}
@GetMapping(value = "/home", produces = MediaType.APPLICATION_JSON_VALUE)
public String home(Model model){
List<TreeNode> nodesList = null;
nodesList = getNodes();
ObjectMapper jsonMapper = new ObjectMapper();
try {
List<String> menuItems = new ArrayList<>();
List<FamilyTree> treesList = familyTreeService.findAll();
treesList.forEach( tree ->{
menuItems.add(tree.getFamilyTreeName());
});
if(!menuItems.isEmpty()){
model.addAttribute("menuItems", menuItems);
}
model.addAttribute("ft_items",
jsonMapper.writeValueAsString(nodesList));
model.addAttribute("profile", new Profile());
} catch (JsonProcessingException e) {
log.warn(e.getMessage());
}
return "/home";
}
@GetMapping(value = "/viewfulltree/{familyTreeId}", produces = MediaType.APPLICATION_JSON_VALUE)
public String getTree(@PathVariable("familyTreeId") String familyTreeId, Model model){
List<TreeNode> nodesList = null;
nodesList = getTreeNodes(Long.valueOf(familyTreeId));
ObjectMapper jsonMapper = new ObjectMapper();
try {
List<String> menuItems = new ArrayList<>();
List<FamilyTree> treesList = familyTreeService.findAll();
treesList.forEach( tree ->{
menuItems.add(tree.getFamilyTreeName());
});
if(!menuItems.isEmpty()){
model.addAttribute("menuItems", menuItems);
}
model.addAttribute("ft_items", jsonMapper.writeValueAsString(nodesList));
model.addAttribute("profile", new Profile());
} catch (JsonProcessingException e) {
log.warn(e.getMessage());
}
return "/viewfulltree";
}
}
注意:我在運行應用程序時發現這兩個文件之間的唯一區別是 url。 我從瀏覽器轉到 home.html 源,然后單擊它提供以下 URL 和找到的 css 文件的任何 css 文件。
found:http://localhost:7030/familytree/webjars/bootstrap/3.3.7/css/bootstrap.min.css
但是當我從瀏覽器查看 viewfulltree.html 源代碼並單擊任何 css 文件時,它給了我下面的 url 並且找不到 css 文件,給出了 404 錯誤。
not-found(404):http://localhost:7030/familytree/viewfulltree/webjars/bootstrap/3.3.7/css/bootstrap.min.css
我無法弄清楚我需要在哪里更改代碼。 如果我需要提供代碼的任何部分,請告訴我。
主頁.html:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Family-tree</title>
<div th:replace="header :: header-css" ></div>
<div th:replace="familytree :: family-tree-css" ></div>
</head>
<body>
<div th:replace="header :: header" ></div>
<section layout:fragment="custom-content">
<div th:replace="familytree :: family-tree" ></div>
</section>
</body>
</html>
頭文件.html:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<div th:fragment="header-css">
<!-- this is header css -->
<link rel="stylesheet" type="text/css" th:href="@{webjars/bootstrap/3.3.7/css/bootstrap.min.css}" />
<style>
h1{
color:#0000FF;
}
h2{
color:#FF0000;
}
footer{
margin-top:60px;
}
</style>
</div>
</head>
<body>
<div th:fragment="header">
<!-- this is header -->
<nav class="navbar navbar-inverse" id="ft_menuItem">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand active" th:href="@{/home}">Family Tree</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Trees
<span class="caret"></span></a>
<ul class="dropdown-menu">
<li th:unless="${#lists.isEmpty(menuItems)}" th:each="menuItem : ${menuItems}">
<a th:href="@{/viewfulltree/2}" th:text="${menuItem}">Create new Tree</a>
</li>
<li class="divider"></li>
<li><a th:href="@{/createtreeform}">Create new Tree</a></li>
</ul>
</li>
<li><a th:href="@{/events}">Event Calendar</a></li>
<li><a th:href="@{/aboutus}">About Us</a></li>
</ul>
</div>
</div>
</nav>
<script th:src="@{webjars/jquery/3.1.1/jquery.min.js}"></script>
<script th:src="@{webjars/bootstrap/3.3.7/js/bootstrap.min.js}"></script>
</div>
</body>
</html>
家譜.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Family-tree</title>
<div th:fragment="family-tree-css">
<link rel="stylesheet" th:href='@{css/jquery-ui-1.10.2.custom.css}'/>
<link th:href='@{css/primitives.latest.css?3710}' media="screen" rel="stylesheet" type="text/css" />
<style type="text/css">
.table-user-information > tbody > tr {
border-top: 1px solid rgb(221, 221, 221);
}
.table-user-information > tbody > tr:first-child {
border-top: 0;
}
.table-user-information > tbody > tr > td {
border-top: 0;
font-size: 13px;
}
.toppad
{
margin-top:20px;
}
</style>
</div>
</head>
<body>
<div th:fragment="family-tree">
<div class="container-fluid">
<div class="row">
<div class="col-md-8 col-lg-8 nopadding">
<div id="btn50">50%</div>
<div id="btn80">80%</div>
<div id="btn100">100%</div>
<div id="btn130">130%</div>
<div id="orgdiagram" style="height: 480px; overflow: hidden; border-style: dotted; border-width: 1px;"></div>
</div>
<div class="col-md-4 col-lg-4 nopadding">
<div class="panel panel-info">
<div class="panel-heading">
<h4 class="panel-title">full Name here</h4>
</div>
<div class="panel-body">
<div class="row">
<div class=" col-md-12 col-lg-12 ">
<table class="table table-user-information">
<tbody>
<tr>
<td><img alt="User Pic" src="images/male.png" class="img-circle img-responsive" width="50px"></img></td>
</tr>
<tr>
<td>Gender</td>
<td>Female</td>
</tr>
<tr>
<td>Age</td>
<td>30</td>
</tr>
<tr>
<td>Date of Birth:</td>
<td>06/23/2013</td>
</tr>
<tr>
<td>Anniversary Date</td>
<td>01/24/1988</td>
</tr>
<tr>
<td>Child Of</td>
<td>Parent Name goes here</td>
</tr>
<tr>
<td>Marital status</td>
<td>Married</td>
</tr>
<tr>
<td>No. of Children</td>
<td>4</td>
</tr>
<tr>
<td>Phone Number</td>
<td>
123-4567-890(Landline)<br></br>
555-4567-890(Mobile)
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="panel-footer">
</div>
</div>
</div>
</div>
</div>
<div id="create-Profile-form" title="Create new user">
<p class="validateTips">All form fields are required.</p>
<form id="add-profile" th:object="${profile}">
<table>
<tr>
<td>
</td>
<td>
<input type="hidden" id="in_parentId" th:field="*{parentId}"></input>
</td>
</tr>
<tr>
<td>
Full Name
</td>
<td>
<input type="text" id="in_profileName" th:field="*{profileName}"/>
</td>
</tr>
<tr>
<td>
First Name
</td>
<td>
<input type="text" id="in_firstName" th:field="*{firstName}"/>
</td>
</tr>
<tr>
<td>
Last Name
</td>
<td>
<input type="text" id="in_lastName" th:field="*{lastName}"/>
</td>
</tr>
<tr>
<td>
Gender
</td>
<td>
<select id="in_gender" th:field="*{gender}" >
<option th:value="male" th:text="Male">Male</option>
<option th:value="female" th:text="Fe-Male">Fe-Male</option>
</select>
</td>
</tr>
</table>
</form>
</div>
<script type="text/javascript" th:src='@{js/bootstrap.min.js}'></script>
<script type="text/javascript" th:src='@{js/jquery-1.9.1.js}'></script>
<script type="text/javascript" th:src='@{js/jquery-ui-1.10.2.custom.min.js}'></script>
<script type="text/javascript" th:src='@{js/primitives.min.js?3710}'></script>
<script th:inline="javascript">
/*<![CDATA[*/
jQuery(document).ready(function () {
var dialog, form;
var treeNodes = [[${ft_items}]];
var options = new primitives.orgdiagram.Config();
var items = [];
var buttons = [];
$('form').on('submit', function(e){
e.preventDefault();
return false;
});
dialog = $("#create-Profile-form").dialog({
autoOpen: false,
height: 400,
width: 350,
modal: true,
buttons: {
"Create an Profile": function(){
var profileData = {};
profileData.profileName = $("#in_profileName").val();
profileData.firstName = $("#in_firstName").val();
profileData.lastName = $("#in_lastName").val();
profileData.gender = $("#in_gender").val(),
profileData.parentId = $("#in_parentId").val();
$.ajax({
type: "POST",
url: "profile/save",
async: true,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
data: JSON.stringify(profileData),
success: function(result){
console.log(result);
dialog.dialog("close");
items = treeNodesToItems(JSON.stringify(result.object));
updateTreeWithItems(items);
$("#add-profile").trigger("reset");
},
error: function(jqXhr, textStatus, errorThrown){
console.log(textStatus);
alert('error:' +textStatus + '\n:' +errorThrown);
}
});
dialog.dialog( "close" );
},
Cancel: function() {
dialog.dialog( "close" );
}
},
close: function() {
//form[ 0 ].reset();
//allFields.removeClass( "ui-state-error" );
$("#add-profile").trigger("reset");
}
});
dialog.dialog("close");
buttons.push(new primitives.orgdiagram.ButtonConfig("add", "ui-icon-person", "Add"));
buttons.push(new primitives.orgdiagram.ButtonConfig("delete", "ui-icon-close", "Delete"));
items = treeNodesToItems(treeNodes);
options.pageFitMode = primitives.common.PageFitMode.None;
options.items = items;
options.buttons = buttons;
options.cursorItem = 0;
options.hasSelectorCheckbox = primitives.common.Enabled.False;
options.onButtonClick = function (e, data) {
switch (data.name) {
case "delete":
if(data.context.parent==null || data.context.parent==''){
alert('you can not delete the parent node')
}
else{
$.ajax({
type: "DELETE",
url: "profile/delete/"+data.context.id,
//dataType: "json",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
} ,
success: function(result){
items = treeNodesToItems(JSON.stringify(result.object));
updateTreeWithItems(items);
console.log(result);
},
error: function(jqXhr, textStatus, errorThrown){
console.log(textStatus);
alert('error:' +textStatus + '\n:' +errorThrown);
}
});
}
break;
case "add":
/* get items collection */
//var items = jQuery("#orgdiagram").orgDiagram("option", "items");
/* create new item */
$('#in_parentId').val(data.context.id);
dialog.dialog( "open" );
break;
}
};
jQuery("#orgdiagram").orgDiagram(options);
$("#btn50").button().click(function () { onScale(0.5); });
$("#btn80").button().click(function () { onScale(.8); });
$("#btn100").button().click(function () { onScale(1); });
$("#btn130").button().click(function () { onScale(1.3); });
});
function treeNodesToItems(treeNodes){
var itemsToIterate = JSON.parse(treeNodes);
var new_items = [];
for(var i=0; i<itemsToIterate.length; i++){
new_items.push(
new primitives.orgdiagram.ItemConfig({
id: itemsToIterate[i].id,
parent: itemsToIterate[i].parent,
title: itemsToIterate[i].title,
description: itemsToIterate[i].description,
image: "images/"+itemsToIterate[i].gender+".png"
}));
}
return new_items;
}
function updateTreeWithItems(ft_items){
jQuery("#orgdiagram").orgDiagram({
items: ft_items
});
jQuery("#orgdiagram").orgDiagram("update", /*Refresh: use fast refresh to update chart*/ primitives.orgdiagram.UpdateMode.Refresh);
}
function onScale(scale) {
if (scale != null) {
jQuery("#orgdiagram").orgDiagram({ scale: scale });
}
jQuery("#orgdiagram").orgDiagram("update", primitives.orgdiagram.UpdateMode.Refresh);
}
/*]]>*/
</script>
</div>
</body>
</html>
轉到您的header-css
片段並像這樣更新您的 css 鏈接
<link rel="stylesheet" type="text/css" th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.min.css}" />
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.