使用springboot实现一个简单的restful crud——03、前端页面、管理员登陆(注销)功能
前言
这一篇我们就先引入前端页面和相关的静态资源,再做一下管理员的登陆和注销的功能,为后续在页面上操作数据做一个基础。
前端页面
前端的页面是我从网上找的一个基于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:
- 将静态资源版本化,更利于升级和维护。
- 剥离静态资源,提高编译速度和打包效率。
- 实现资源共享,有利于统一前端开发。
怎么使用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、前端页面、管理员登陆(注销)功能的更多相关文章
- 使用springboot实现一个简单的restful crud——01、项目简介以及创建项目
前言 之前一段时间学习了一些springboot的一些基础使用方法和敲了一些例子,是时候写一个简单的crud来将之前学的东西做一个整合了 -- 一个员工列表的增删改查. 使用 restful api ...
- 使用springboot实现一个简单的restful crud——02、dao层单元测试,测试从数据库取数据
接着上一篇,上一篇我们创建了项目.创建了实体类,以及创建了数据库数据.这一篇就写一下Dao层,以及对Dao层进行单元测试,看下能否成功操作数据库数据. Dao EmpDao package com.j ...
- 使用webpy创建一个简单的restful风格的webservice应用
下载:wget http://webpy.org/static/web.py-0.38.tar.gz解压并进入web.py-0.38文件夹安装:easy_install web.py 这是一个如何使用 ...
- 使用springboot写一个简单的测试用例
使用springboot写一个简单的测试用例 目录结构 pom <?xml version="1.0" encoding="UTF-8"?> < ...
- springboot搭建一个简单的websocket的实时推送应用
说一下实用springboot搭建一个简单的websocket 的实时推送应用 websocket是什么 WebSocket是一种在单个TCP连接上进行全双工通信的协议 我们以前用的http协议只能单 ...
- 【SpingBoot】 测试如何使用SpringBoot搭建一个简单后台1
很久没写博客了,最近接到一个组内的测试开发任务是做一个使用SpringBoot 开发一个后台程序(还未完成),特写感想记录一下 1. 为什么选择SpringBoot ? 首先是目前很多公司的后台还是J ...
- 基础项目构建,引入web模块,完成一个简单的RESTful API 转载来自翟永超
简介 在您第一次接触和学习Spring框架的时候,是否因为其繁杂的配置而退却了?在你第n次使用Spring框架的时候,是否觉得一堆反复粘贴的配置有一些厌烦?那么您就不妨来试试使用Spring Boot ...
- laravel 实现一个简单的 RESTful API
创建一个 Article 资源 php artisan make:resource Article 你可以在 app/Http/Resources 目录下看到你刚刚生成的 Article 资源 当然我 ...
- 实现iOS图片等资源文件的热更新化(五): 一个简单完整的资源热更新页面
简介 一个简单的关于页面,有一个图片,版本号,App名称等,着重演示各个系列的文章完整集成示例. 动机与意义 这是系列文章的最后一篇.今天抽空写下,收下尾.文章本身会在第四篇的基础上,简单扩充下代码, ...
随机推荐
- Real-time Multiple People Tracking with Deeply Learned Candidate Selection and Person Re-identification
Real-time Multiple People Tracking with Deeply Learned Candidate Selection and Person Re-identificat ...
- freeNAS nfs linux挂载
新建存储块,设置权限为root wheel 备份修改/var/lib/nova 名称 新建/var/lib/nova 目录,修改目录的属主机权限 mv /var/lib/nova /var/lib/n ...
- centos7.6环境编译安装php-7.2.24修复最新 CVE-2019-11043 漏洞
先编译安装php-7.2.24,然后编译安装扩展 主版本地址地址:https://www.php.net/distributions/php-7.2.24.tar.gz # 编译 php-7.2.24 ...
- BDD介绍
TDD: TDD(Test-Drivern Development)测试驱动开发,是敏捷开发中的一项核心实践和技术,也是一种设计方法论.TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代 ...
- 数据分析入门——pandas之DataFrame多层/多级索引与聚合操作
一.行多层索引 1.隐式创建 在构造函数中给index.colunms等多个数组实现(datafarme与series都可以) df的多级索引创建方法类似: 2.显式创建pd.MultiIndex 其 ...
- oracle的merge语法
merge into trade.ttradeseat ausing trade.bs_zrt_tradeseat bon (a.L_FUND_ID = b.l_Fund_Id and a.l_bas ...
- [LeetCode] 804. Unique Morse Code Words 独特的摩斯码单词
International Morse Code defines a standard encoding where each letter is mapped to a series of dots ...
- Kubernetes 服务质量 Qos 解析 - Pod 资源 requests 和 limits 如何配置?
QoS是 Quality of Service 的缩写,即服务质量.为了实现资源被有效调度和分配的同时提高资源利用率,kubernetes针对不同服务质量的预期,通过 QoS(Quality of S ...
- Jetson TX2
NVIDIA Jetson TX2作为一个嵌入式平台的深度学习端,具备不错的GPU性能,可以发现TX2的GPU的计算能力是6.2.这意味着TX2对半精度运算有着良好的支持,因此,完全可以在桌面端训练好 ...
- [转帖]首颗国产DRAM芯片的技术与专利,合肥长鑫存储的全面深度剖析
首颗国产DRAM芯片的技术与专利,合肥长鑫存储的全面深度剖析 https://mp.weixin.qq.com/s/g_gnr804q8ix4b9d81CZ1Q 2019.11 存储芯片已经成为全球珍 ...