前言

这一篇我们就先引入前端页面和相关的静态资源,再做一下管理员的登陆和注销的功能,为后续在页面上操作数据做一个基础。

前端页面

前端的页面是我从网上找的一个基于Bootstrap 的dashboard模板,可以用来作为后台管理的界面,前端页面代码繁多,我只贴一些重要的,就不全部贴出来了。

引入静态资源

<!-- Bootstrap core CSS -->
<!--公共资源通过webjars引入-->
<link href="/asserts/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}" rel="stylesheet"> <!-- Custom styles for this template -->
<!--自定义资源通过普通方式引入-->
<link href="/asserts/css/signin.css" th:href="@{/asserts/css/signin.css}" rel="stylesheet">

要使用th:href,要先倒入thymeleaf命名空间。

添加xmlns:th="http://www.thymeleaf.org"。idea就会出语法提示。

webjars:

    1. 将静态资源版本化,更利于升级和维护。
    1. 剥离静态资源,提高编译速度和打包效率。
    1. 实现资源共享,有利于统一前端开发。

怎么使用webjars呢?

依赖

<!--通过webjar引入前端库-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.0.0</version>
</dependency>

可以在官网快速找到各种常用前端库的引用:https://www.webjars.org/

资源所在位置

项目External Libraries文件夹:

webjars映射规则

th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}"

所有/webjars/**的url 都去classpath:/META-INF/resources/webjars/找资源。

springboot资源映射规则

以"/**"访问当前项目的任何资源都会首先去如下路径寻找,这些路径是静态资源的文件夹:

classpath:/META-INF/resources/,

classpath:/resources/,

classpath:/static/,

classpath:/public/

ps: classpath src->main->resources文件夹

#可以在配置文件中修改静态资源文件路径
spring:
resources:
static-locations:

th:href="@{/asserts/css/signin.css}"

我的sign.css是放在classpath:/static/asserts/css文件夹下

禁止自动填充

现在很多浏览器都会把cookie信息自动填充到我们的表单中,我们如果想要禁止自动填充,怎么做呢?

<input name="username" autocompleted="off" type="text" class="form-control" placeholder="Username" th:placeholder="#{login.username}" required="" autofocus="">

<input name="password" autocomplete="new-password" autocompleted="off" type="password" class="form-control" th:placeholder="#{login.password}" placeholder="Password" required="">

在username中添加autocompleted="off"

在password中添加autocomplete="new-password" autocompleted="off"

扩展springmvc

在config包下新建MyMvcConfig类实现了WebMvcConfigurer接口,然后实现了addViewControllers方法。

package com.jotal.springboot08restfulcrud.config;

/*
* 不能使用@EnableWebMvc,使用了就是全面接管springmvc,自动配置就会失效
* 实现WebMvcConfigurer,来扩展springmvc的功能
* */
@Configuration
public class MyMvcConfig implements WebMvcConfigurer { //识图适配器
@Override
public void addViewControllers(ViewControllerRegistry registry) { //登陆
registry.addViewController("/login").setViewName("login");
registry.addViewController("/").setViewName("login");
registry.addViewController("/login.html").setViewName("login");
} }

springboot已经帮我们自动配置好了springmvc,我们为什么还要扩展springmvc?

例如我们需要项目一启动就跳转到一个页面,我们以往可能会写一个Controller方法来跳转,但是方法里没有什么内容,这样就显得很浪费。这时候我们就可以addViewControllers中添加视图适配规则。不仅仅是视图适配,我们还可以扩展拦截器、国际化等,来丰富系统功能。这些将会在下面介绍到。

registry.addViewController("/").setViewName("login"); 这句话就定义了项目一启动就跳转login页面。

/login和/login.html都会跳转到login页面。那么是怎么通过一个字符串“login”就会跳转到login.html呢?是thymeleaf视图解析器完成的。

thymeleaf视图解析器

初始化的默认页面路径在classpath:/templates/ 下,视图后缀为.html。默认路径也可以在配置文件中修改。

管理员登陆、注销

下面我们开始写管理员登陆、注销相关功能

实体类

package com.jotal.springboot08restfulcrud.entities;

public class User {

    private String username;
private String password;
//getter、setter、constructor、toString
}

Dao

@Mapper
public interface UserDao {
int login(User user);
}

映射文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.jotal.springboot08restfulcrud.dao.UserDao"> <select id="login" parameterType="user" resultType="Integer">
select count(*) from user
where username=#{username} and password=#{password}
</select> </mapper>

Service

@Service
public class UserServiceImpl implements UserService {
@Autowired
UserDao userDao;
@Override
public int login(User user) {
return userDao.login(user);
}
}

Controller

@Controller
@RequestMapping(value = "/user")
public class UserController {
@Autowired
UserServiceImpl userService; @PostMapping(value = "/login")
public String login(@RequestParam("username") String username,
@RequestParam("password") String password,
Map<String,Object> map,
HttpSession session){ User user = new User(username, password);
if(userService.login(user)>0){
//登录成功,为了防止表单重复提交,利用重定向
session.setAttribute("loginUser", username);
return "redirect:/main";
}else{
// 登陆失败
map.put("msg","用户名或密码错误");
return "login";
} } // 用户注销
@GetMapping("/logout/{username}")
public String logout(@PathVariable("username") String username,HttpSession session) {
// 清除session
session.invalidate();
return "redirect:/login";
}
}

首先form表单中的请求路径定义为该Controller方法,用POST方法提交

<form class="form-signin" th:action="@{/user/login}" method="post">

然后分别在用户名和密码框的输入框加上name属性,方便springmvc取值参数。springmvc用@RequestParam("xxx")取得前端请求发送来的参数值。

name="username"   name="password"

我们利用拿到的数据和数据库中用户名密码是否一致,判断是否成功登陆。如果登陆成功,就将用户名添加到session中,然后重定向到主页。

如果用户名或者密码不对,就利用Map添加一个包含提示信息的属性到视图中,然后回到login.html。

这里利用thymeleaf的 th:if 判断决定msg是否显示。判断msg不为空段落才会显示

<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>

登陆进到主页之后,如果刷新主页的页面,会发现浏览器弹窗提示登陆表单会重复提交。这种情况利用重定向来解决!

return "redirect:/main"; 就是这一句 重定向到main,然后在我们扩展springmvc的地方加入适配main的规则。

//登录成功之后,重定向解决表单重复提交问题
registry.addViewController("/main").setViewName("dashboard");

所以最终由thymeleaf视图解析器最终转发到主页dashboard.html。

拦截器

登陆功能怎么能少得了拦截器?拦截器在登陆功能中主要是为了防止在未登录的情况下通过uri的方式访问需要权限的页面。我们看一下如何在springboot中定义拦截器。

我们在component新建LoginHandlerInterceptor类实现HandlerInterceptor类。

package com.jotal.springboot08restfulcrud.component;

public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
Object user = session.getAttribute("loginUser");
if (user == null) {
// 未登录返回登录页面
request.setAttribute("msg","未登录,请先登录");
request.getRequestDispatcher("/login").forward(request,response);
return false;
}else{
return true;
}
} @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { }
}

我们判断session中是否存在loginUser,loginUser是我们登陆成功才会添加到session中的。如果loginUser不存在,就在request中添加msg提示信息,然后转发到登录页面。如果loginUser存在就直接放行。

我们实现了拦截器,还要加入到springmvc的环境中。在MyMvcConfig中类重写addInterceptors方法。

//拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/login","/","/login.html","/user/login","/webjars/**","/asserts/**");
}

我们定义了拦截规则,就是除了"/login","/","login.html","/user/login"之外的所有uri都会被拦截下来进行判断再决定是否放行。/user/login 是用来提交登陆表单请求的,"/login","/","login.html"是转发到登录页的。springboot已经默认静态资源不会被拦截器拦截。

注销

@GetMapping("/logout/{username}")

这样的请求会转发到实现注销的Controller方法。这里使用了restful api风格

我们使用@PathVariable("username")来获取参数,然后清除session并重定向到login.html。

//    用户注销
@GetMapping("/logout/{username}")
public String logout(@PathVariable("username") String username,HttpSession session) {
// 清除session
session.invalidate();
return "redirect:/login";
}

测试

输入错误账号密码

不登录访问主页http://localhost:8080/crud/main

注销后访问主页http://localhost:8080/crud/main

**主页**
![](https://img2018.cnblogs.com/blog/1738909/201908/1738909-20190813134917807-918042939.png)

今天这篇就到这里了,今天讲了前端页面和登录注销的功能,另外还有springboot静态资源的映射规则,thymeleaf的视图解析规则,以及扩展springmvc的功能。下面我们会讲一些国际化的问题,以及正式开始在页面中进行数据操作。

使用springboot实现一个简单的restful crud——03、前端页面、管理员登陆(注销)功能的更多相关文章

  1. 使用springboot实现一个简单的restful crud——01、项目简介以及创建项目

    前言 之前一段时间学习了一些springboot的一些基础使用方法和敲了一些例子,是时候写一个简单的crud来将之前学的东西做一个整合了 -- 一个员工列表的增删改查. 使用 restful api ...

  2. 使用springboot实现一个简单的restful crud——02、dao层单元测试,测试从数据库取数据

    接着上一篇,上一篇我们创建了项目.创建了实体类,以及创建了数据库数据.这一篇就写一下Dao层,以及对Dao层进行单元测试,看下能否成功操作数据库数据. Dao EmpDao package com.j ...

  3. 使用webpy创建一个简单的restful风格的webservice应用

    下载:wget http://webpy.org/static/web.py-0.38.tar.gz解压并进入web.py-0.38文件夹安装:easy_install web.py 这是一个如何使用 ...

  4. 使用springboot写一个简单的测试用例

    使用springboot写一个简单的测试用例 目录结构 pom <?xml version="1.0" encoding="UTF-8"?> < ...

  5. springboot搭建一个简单的websocket的实时推送应用

    说一下实用springboot搭建一个简单的websocket 的实时推送应用 websocket是什么 WebSocket是一种在单个TCP连接上进行全双工通信的协议 我们以前用的http协议只能单 ...

  6. 【SpingBoot】 测试如何使用SpringBoot搭建一个简单后台1

    很久没写博客了,最近接到一个组内的测试开发任务是做一个使用SpringBoot 开发一个后台程序(还未完成),特写感想记录一下 1. 为什么选择SpringBoot ? 首先是目前很多公司的后台还是J ...

  7. 基础项目构建,引入web模块,完成一个简单的RESTful API 转载来自翟永超

    简介 在您第一次接触和学习Spring框架的时候,是否因为其繁杂的配置而退却了?在你第n次使用Spring框架的时候,是否觉得一堆反复粘贴的配置有一些厌烦?那么您就不妨来试试使用Spring Boot ...

  8. laravel 实现一个简单的 RESTful API

    创建一个 Article 资源 php artisan make:resource Article 你可以在 app/Http/Resources 目录下看到你刚刚生成的 Article 资源 当然我 ...

  9. 实现iOS图片等资源文件的热更新化(五): 一个简单完整的资源热更新页面

    简介 一个简单的关于页面,有一个图片,版本号,App名称等,着重演示各个系列的文章完整集成示例. 动机与意义 这是系列文章的最后一篇.今天抽空写下,收下尾.文章本身会在第四篇的基础上,简单扩充下代码, ...

随机推荐

  1. Linux 踢掉其他终端用户

    输入W查看信息 root@HAN:~# w 09:02:36 up 8 days, 20:10, 1 user, load average: 0.00, 0.00, 0.00 USER TTY FRO ...

  2. 第06组 Beta冲刺(5/5)

    队名:拾光组 组长博客链接 作业博客链接 团队项目情况 燃尽图(组内共享) 组长:宋奕 过去两天完成了哪些任务 继续维护后端代码 准备beta版本的答辩 GitHub签入记录 接下来的计划 整理任务, ...

  3. 关于高负载服务器Kernel的ipv4的TCP参数说明及优化

    net.ipv4.tcp_mem 内核分配给TCP连接的内存,单位是Page,1 Page = 4096 Bytes,可用命令查看: #getconf PAGESIZE 4096 net.ipv4.t ...

  4. 回顾idea快捷键

    F9            resume programe 恢复程序 Alt+F10       show execution point 显示执行断点 F8            Step Over ...

  5. 品优购商城项目(五)消息中间件 ActiveMQ

    消息中间件用于降低各个项目模块的耦合,适用于不需要等待返回消息才能进入下一个业务环节的模块,以及实时要求性不高的业务模块. 一.JMS JMS(Java Messaging Service)是Java ...

  6. 服务器推送(Server push)技术总结

    1. 短轮询 ajax按一定间隔去请求 2. 长轮询(long Polling) Long Polling的实现很简单,可分为四个过程: 发起Polling发起Polling很简单,只需向服务器发起请 ...

  7. iOS - 点击按钮实现简单的复制功能

    UIPasteboard使用 基本使用: - (void)copyClick { UIPasteboard *pab = [UIPasteboard generalPasteboard]; pab.s ...

  8. [LeetCode] 21. Merge Two Sorted Lists 合并有序链表

    Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...

  9. java里的 int vs Integer

    int vs Integer 基本类型int的默认值为0;对应的封装类型Integer的默认值为null Integer对象会占用更多的内存.Integer是一个对象,需要存储对象的元数据.但是int ...

  10. PCL贪婪投影三角化算法

    贪婪投影三角化算法是一种对原始点云进行快速三角化的算法,该算法假设曲面光滑,点云密度变化均匀,不能在三角化的同时对曲面进行平滑和孔洞修复. 方法: (1)将三维点通过法线投影到某一平面 (2)对投影得 ...