springboot-项目

1.导入静态资源:

结构如图所示:
html文件放在templates文件夹下(不可直接访问,只能通过controller跳转访问),其他放在static文件夹下。
在这里插入图片描述
注:注意修改html页面中的链接地址将其改为thymeleaf格式(要记得加thymeleaf的依赖和头文件)
如:

<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
<img class="mb-4" th:src="@{/img/bootstrap-solid.svg}" alt="" width="72" height="72">

URL表达式@{…}
使用@{…}括起来,并且其中只能写一个绝对URL或相对URL地址的表达式,称为URL表达式。这个绝对/相对URL地址中一般是包含有动态参数的,需要结合变量表达式${…}进行字符串拼接。
在URL表达式中,Thymeleaf会将开头的斜杠(/)解析为当前工程的上下文路径ContextPath,而浏览器会自动为其添加“http://主机名:端口号”,即其即为一个绝对路径

2.用户登录:

效果:一输入url就跳转到登录的index页面,表单登录,在后台对输入的数据进行判断,若正确跳转到用户表页面,若错误跳转登录页面并输出提示信息。并且用户不可以在没有登录的情况下直接访问用户表页面,会出现信息提示。

2.1 首页设置

2.1.1 首页跳转

因为templates文件夹下的页面不可以直接访问,所以我们要先定义一个视图跳转。
方法一:
在controller中编写(不推荐)

@RequestMapping("/")
    public String index(){
        return "index";
    }

方法二:
自定义mvc配置:在congif文件夹下创建myMvcConfig,这样不管我们是直接打开还是输入index.html都可以直接到登录页面。(推荐)

@Configuration
public class myMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/main.html").setViewName("dashboard");
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");
    }

注:在这个项目中不管是否设置,打开项目都是直接到登录页面的。因为在前一章的笔记我们可以看到源码中设置,springboot会自动的将templates文件夹下的index.html设置为首页。
还需要注意config文件夹的位置要不然配置不生效!

2.1.2 登录验证

将表单提交到 /user/index

<form class="form-signin" th:action="@{/user/index}">
<input type="text" name="username" class="form-control"  placeholder="Username" required="" autofocus="">
<input type="password" name="pwd" class="form-control"  placeholder="Password" required="">

如果输入有错误就显示错误提示,这里使用了thymeleaf的语法。
th:if 该属性用于逻辑判断
#strings:关于字符串的thymeleaf的内置对象,如果msg为空,则显示提示信息。

<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"/>
public class indexController {
    @RequestMapping("/user/index")
    public String index(@RequestParam("username") String username, @RequestParam("pwd")String pwd, Model model, HttpSession session){
        if(username.equals("www") && "1234".equals(pwd)){
            session.setAttribute("loginName",username);
            return "redirect:/main.html";
        }else {
            model.addAttribute("msg","输入错误");
            return "index";
        }
    }
}

在这里我们会发现登录成功后的url显示的非常的。。简陋
所以我们设置了一个“假”的页面main.html,将dashboard.html映射到此页面上
return “redirect:/main.html”;

在这里插入图片描述

2.2 拦截器

思路:设置拦截器,在登录页面将值传入session表示登录成功,通过session是否为空来判断是否需要拦截。

  1. 在congfig目录下创建myLoginInterceptor
    如果session中没有值,就输出提示信息然后转发回去。
public class myLoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object username = request.getSession().getAttribute("loginName");
        if (username == null){
            request.setAttribute("msg","没有权限");
            request.getRequestDispatcher("/index.html").forward(request,response);
            return false;
        }else {
            return true;
        }
    }
}
  1. 在myMvcConfig中添加拦截的路径
    excludePathPatterns():添加不被拦截的资源(静态资源和登录页面)
    注:/** 表示所有文件包括文件夹,/* 表示所有文件。
@Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new  myLoginInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/index.html","/","static/**","/user/index");

    }

另:我们还可以利用session中的值在用户页面显示用户名,这里的[[${session.loginName}]]等同于

th:text="${msg}"
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">[[${session.loginName}]]</a>

3.员工列表展示:

3.1 代码复用实现:

我们发现首页和员工列表页面的顶部导航栏和侧边栏都是相同的,我们用thymeleaf的th:fragment:语法达到代码复用。这样我们只需要修改一处的代码所有的样式就都修改了。

  1. 将要复用的代码放在单独的类中:commons下的commen,分别设置他们的名称为topbar和sidebar。
    注:在html中,nav标签是html5版本中新增的标签,是使用来定义导航链接的部分。nav标签只是用来表示该区域是导航链接,默认并没有什么显示效果。
    th:fragment:定义代码块,方便被th:insert引用。
    在这里插入图片描述

  2. 在页面对应的地方引用:
    ~{…}: 代码块表达式
    推荐写法:~{templatename::fragmentname}
    支持写法:~{templatename::#id}
    templatename:模版名,Thymeleaf会根据模版名解析完整路径:/resources/templates/templatename.html,要注意文件的路径。
    fragmentname:片段名,Thymeleaf通过th:fragment声明定义代码块,即:th:fragment=“fragmentname”
    id:HTML的id选择器,使用时要在前面加上#号,不支持class选择器。支持:~{templatename::#id}
    代码块表达式需要配合th属性(th:insert,th:replace,th:include)一起使用。
    th:insert:将代码块片段整个插入到使用了th:insert的HTML标签中,
    th:replace:将代码块片段整个替换使用了th:replace的HTML标签中,
    th:include:将代码块片段包含的内容插入到使用了th:include的HTML标签中,

<nav th:replace="~{commons/common::topbar}"></nav>
<nav th:replace="~{commons/common::sidebar}"></nav>

3.2 controller层编写:

编写跳转到员工列表页面的程序。
需要在employeeDao中添加@Repository注解,然后注意要写全类名,要不然会报错。
修改导航栏代码中的对应路径。

@Controller
public class employeeController {
    @Autowired
    com.example.demo.dao.employeeDao employeeDao;

    @RequestMapping("/employee.html")
    public String getEmployee(Model model){
        Collection employee = employeeDao.getEmployee();
        model.addAttribute("emps",employee);
        return "employ/list";
    }
}

将组件通过注解的方法加入到spring容器中:
controller层:@Controller
service层:@Service
Dao层:@Repository
通过@Autowired对属性进行标记,完成自动装配工作。

3.3 设置侧边栏点击高亮

高亮原理:

nav-link active //表示高亮
nav-link //表示常规

在每个页面侧边栏的复用代码上加上一个传入active的值:

<nav th:replace="~{commons/common::sidebar(active='main')}"></nav>
<nav th:replace="~{commons/common::sidebar (active='list')}"></nav>

然后在侧边栏内的代码中进行判断:
注:thymeleaf中要使用 ’ ’ 而不是 “ ” 。
(可能会报错系统识别不到active但是可以运行成功。)

<a th:class="${active == 'main' ?'nav-link active':'nav-link'}" th:href="@{/main.html}">
<a th:class="${active == 'list'?'nav-link active':'nav-link'}" th:href="@{/employee.html}">

用到了thymeleaf的三目表达式:
Conditional operators:
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)

3.4 员工信息显示

th:each属性用于迭代循环,语法:th:each=“obj,iterStat:${objList}”

<tbody>
		<tr th:each="emp:${emps}">
			<td th:text="${emp.getId()}"> </td>
			<td th:text="${emp.getName()}"> </td>
			<td th:text="${emp.getAge()}"> </td>
			<td th:text="${emp.getGender() == 0 ?'男' : '女'}"></td>
			<td th:text="${emp.getBirth()}"> </td>
			<td th:text="${emp.department.getDepartmentName()}"></td>
			<td>
				<button class="btn btn-sm btn-primary">编辑</button>
				<button class="btn btn-sm btn-danger">删除</button>
			</td>
		</tr>
</tbody>

可以用#dates.format() 用来格式化日期时间
${#dates.format(date, ‘dd/MMM/yyyy HH:mm’)}
${#dates.arrayFormat(datesArray, ‘dd/MMM/yyyy HH:mm’)}
${#dates.listFormat(datesList, ‘dd/MMM/yyyy HH:mm’)}
${#dates.setFormat(datesSet, ‘dd/MMM/yyyy HH:mm’)}

4.员工信息添加:

4.1 编写添加页面:

在bootstrap网站上找到需要的表单样式,运用到页面中。
注:

  1. main标签不可缺少,元素中的内容对于文档来说应当是唯一的。它不应包含在文档中重复出现的内容,比如侧栏、导航栏、版权信息、站点标志或搜索表单。这里的main标签内包括了表单主体的样式,如果不写main标签表单是显示不出来的,会被侧边栏覆盖掉。
  2. label 标签的 for 属性:for 属性规定 label 与哪个表单元素绑定(与id绑定)。
  3. input标签的value属性是这个表单提交上去的真实的值。
  4. 因为我们的是通过传入部门id查找部门名称来添加部门的,下拉列表也是通过循环来进行值的显示。
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
            <form th:action="@{/addemp}" method="post">
                <div class="form-group">
                    <label for="name">姓名</label>
                    <input type="text" class="form-control" id="name" name="name">
                </div>
                <div class="form-group">
                    <label for="age">年龄</label>
                    <input type="text" class="form-control" id="age" name="age">
                </div>
                <!--    单选框-->
                <label class="radio-inline">
                    <input type="radio" name="gender" id="inlineRadio1" value="0"></label>
                <label class="radio-inline">
                    <input type="radio" name="gender" id="inlineRadio2" value="1"></label>
                <!--    输入框-->

                <div class="form-group">
                    <label for="birth">生日</label>
                    <input type="text" class="form-control" id="birth" name="birth">
                </div>
                <div class="form-group">
                    <label>部门名称</label>
                    <select class="form-control" name="department.id">
                        <option th:each="department:${departments}" th:text="${department.getDepartmentName()}" th:value="${department.getId()}"></option>
                    </select>
                </div>
                <button type="submit" class="btn btn-default">提交</button>
            </form>
        </main>

4.2 页面完善:

在list页面添加对应的按钮:在后台获得部门名称的集合。

<a th:href="@{/addemp}" class="btn btn-sm btn-success" style="float: right">添加</a>
@GetMapping("/addemp")
    public String addEmp(Model model){
        //显示部门
        Collection departments = departmentDao.getDepartment();
        model.addAttribute("departments",departments);
        return "employ/add";
    }

在form表单中添加提交方法指定为post提交,通过PostMapping来通过不同的提交方法跳转不同的页面,如果不设置提交方式会报错。

@PostMapping("/addemp")
    public String addEmp(Employee employee){
        employeeDao.add(employee);
        return "redirect:/employee";
    }

5. 修改和删除员工信息:

1.编写按钮路径:

通过将id传入到后台进行操作

<a class="btn btn-sm btn-primary" th:href="@{/update/}+${emp.getId()}">编辑</a>
<a class="btn btn-sm btn-danger" th:href="@{/delete/}+${emp.getId()}">删除</a>

对应的controller:

@GetMapping("/update/{id}")
    public String updateEmp(@PathVariable("id") Integer id,Model model){
        Employee employeeById = employeeDao.getEmployeeById(id);
        model.addAttribute("updateEmploy",employeeById);
        //显示部门
        Collection departments = departmentDao.getDepartment();
        model.addAttribute("departments",departments);
        return "employ/update";
    }
    @PostMapping("/update")
    public String updateEmp2(Employee employee){
        employeeDao.add(employee);
        return "redirect:/employee";
    }

删除对应的controller:

//删除页面
    @RequestMapping("/delete/{id}")
    public String delete(@PathVariable("id")Integer id){
        employeeDao.deleteById(id);
        return "redirect:/employee";
    }

2.页面编辑:

添加一个隐藏域:

<input type="hidden" name="id" th:value="${updateEmploy.getId()}">

设置表单的默认值:

 <input type="text" class="form-control" id="name" name="name" th:value="${updateEmploy.getName()}">
//设置单选框的默认值
 <input type="radio" th:checked="${updateEmploy.getGender()==0}" name="gender" id="inlineRadio1" value="0">
//设置下拉框的显示
 <select class="form-control" name="department.id">
     <option th:each="department:${departments}" th:text="${department.getDepartmentName()}" th:value="${department.getId()}" th:selected="${department.getId()==updateEmploy.getDepartment().getId()}"></option>
 </select>

3.注:

将404页面放在error文件夹下,idea会默认识别404.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值