我是他们新的模板引擎。我有一个使用他们的模板引擎的spring boot web应用程序。以下是我的项目结构。
我有home.html
我在其中调用了标题(在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
我无法弄明白我需要在哪里更改代码。请告诉我如果需要提供代码的任何部分。
home.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>
header.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>
familytree.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>
答案 0 :(得分:1)
转到您的header-css
片段并更新您的css链接
<link rel="stylesheet" type="text/css" th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.min.css}" />