Spring 全家桶之 Spring Boot 2.6.4(六)- Web Develop(Part B)
“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。”
三、登录功能开发
登录页面以及Dashboard页面均可在 Bootstrap官网 获取
新建LoginController,增加login方法来处理登录请求,login方法中只要求前端输入用户名为lilith且password为pc12138才可以返回dashboard页面
@Controller
public class LoginController {
@PostMapping("/user/login")
public String login(@RequestParam("username") String username, @RequestParam("password") String password,
Map<String, Object> map){
if ("lilith".equals(username) && "pc12138".equals(password)){
// 用户名lilith,密码为pc12138即可登录成功
return "dashboard";
} else {
// 登录失败
map.put("msg", "用户名密码错误");
return "index";
}
}
}
当验证失败时,将错误信息放在map中,并使用Thymeleaf模板引擎渲染出错误提示信息。
修改index.html页面登录表单提交地址为/user/login,表单提交的method为post。重新启动应用,进入localhost:8080并在登录表单输入正确的用户名和密码;点击登录
页面报错404,并且服务端报错username参数不存在
这是因为在用户名和密码的input框没有name属性,请求的body中也就没有username和password这两个key,Spring MVC也就无法获取这两个参数。
这里修改html页面可能会由于thymeleaf缓存导致修改不会生效,可以开启禁用thymeleaf缓存
# 禁用thymeleaf缓存
spring.thymeleaf.cache=false
页面修改完成之后需要重新编译。
重新启动应用,输入正确的用户名密码之后,点击登录
浏览器跳转到dashboard页面。
重新回到登录页面,输入错误的用户名和密码,点击登录
页面重新跳转到登录页面,没有显示在login方法中定义的错误信息;要想在页面显示错误消息,需要使用Thymeleaf模板引擎;可以参考Thymeleaf官方文档 7.1 Simple conditionals: “if” and “unless”。
Please sign in下面添加P标签
<!--判断,只有输入的用户名密码错误是才会显示p标签,既map不为空的时候显示p标签-->
<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
重新启动应用,输入错误的用户名和密码并点击登录
通过Thymeleaf模板引擎已经成功获取map中报错的错误提示消息并显示在页面上。
解决表单重复提交的问题
在登录成功之后虽然页面可以跳转到dashboard页面,但是浏览器的URL地址仍然是user/login,这是表单提交的地址,如果刷新首页会出现重提提交表单的提示。
解决这个问题最好是重定向到dashboard页面,而不是直接返回dashboard页面,首先要增加一个视图映射
public void addViewControllers(ViewControllerRegistry registry) {
// 浏览器发送 /lilith 页面跳转到success页面
registry.addViewController("/lilith").setViewName("success");
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/dashboard").setViewName("dashboard");
}
修改login方法,重定向到dashboard
@PostMapping("/user/login")
public String login(@RequestParam("username") String username, @RequestParam("password") String password,
Map<String, Object> map){
if ("lilith".equals(username) && "pc12138".equals(password)){
// 用户名为lilith,密码为pc12138即可登录成功
// 防止表单提交,重定向到dabshboard
return "redirect:/dashboard";
} else {
// 登录失败
map.put("msg", "用户名密码错误");
return "index";
}
}
重新启动应用,再次测试,浏览器的地址已经不再是表单提交的地址了,并且不会发生表单提交的问题,资源加载的问题也解决了。
但是还有一个问题,就是该页面没有做权限控制,也就是说在浏览器输入这个地址可以直接进入该页面无需登录,更没有登录提示;这时候就可以使用拦截器进行登录检查,只有登录之后才能进入该页面。
在这之前要修改login方法,将登录后的用户信息保存在session中
@PostMapping("/user/login")
public String login(@RequestParam("username") String username, @RequestParam("password") String password,
Map<String, Object> map, HttpSession session){
if ("lilith".equals(username) && "pc12138".equals(password)){
// 用户名为lilith,密码为pc12138即可登录成功
// 防止表单提交,重定向到dabshboard
session.setAttribute("currentUser",username);
return "redirect:/dashboard";
} else {
// 登录失败
map.put("msg", "用户名密码错误");
return "index";
}
}
接着在config包下新建一个登录拦截器
public class LilithHandlerInterceptor implements HandlerInterceptor {
// 目标方法执行前
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// session中获取登录用户
Object currentUser = request.getSession().getAttribute("currentUser");
if (currentUser == null){
// 未登录的情况,拦截
request.setAttribute("msg","请先登录");
request.getRequestDispatcher("/index.html").forward(request,response);
return false;
} else {
// 已经登录,放行
return true;
}
}
}
在config包下的LilithMvcCofnig配置类中注册拦截器
// 注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LilithHandlerInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/index.html","/","/user/login");
}
重启应用,在火狐浏览器中输入 http://localhost:8080/dashboard
显示登录界面,说明拦截器生效了,但是页面样式丢失,说明静态资源也被拦截掉了,需要对静态资源放行
修改注册的拦截器
// 注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LilithHandlerInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/index.html","/","/user/login","/asserts/**","/webjars/**");
}
重新启动应用,浏览器中再次输入 http://localhost:8080/dashboard
页面样式已经正常
REST 风格 URL 定义
REST是一种软件架构风格,或者说是一种规范,其强调HTTP应当以资源为中心,并且规范了URI的风格;规范了HTTP请求动作(GET/PUT/POST/DELETE/HEAD/OPTIONS)的使用,具有对应的语义。
根据REST风格定义CRUD的URL
操作 | URI | Method |
---|---|---|
查询所有 | list | GET |
查询单个 | employee/{id} | GET |
进入添加页面 | employee | GET |
添加操作 | employee | POST |
进入修改页面 | edit/{id} | GET |
保存操作 | employee | PUT |
删除操作 | employee/{id} | DELETE |
相关文章
- spring容器初始化过程中出现异常_spring容器什么时候启动
- Spring 全家桶之 Spring Boot 2.6.4(六)- Web Develop(Part A)
- Spring 全家桶之 Spring Boot 2.6.4(八)- 嵌入式 Servlet 容器(Part A)
- 只会用 Spring Boot 创建微服务?那你就 OUT 了,还有这 4 种替代方案!
- spring boot整合shiro_Spring框架介绍及使用
- Spring Boot、Spring Cloud 自定义配置文件(如何整合配置中心)
- Spring Boot基础配置之属性配置
- Spring Boot - ApplicationRunner && CommandLineRunner扩展接口
- spring boot 配置文件properties和YAML详解
- spring boot支持https请求(建议收藏)
- Spring Cloud 2020.0.4 发布!
- Spring Boot的Web应用开发
- 使用Spring Cloud Feign实现微服务的负载均衡(二)
- Spring Boot 2.0 多图片上传加回显
- jms+spring+activemq配置(发送和接收消息)详解编程语言
- Spring Boot入门第四天:使用Thymeleaf模板引擎详解编程语言
- Spring Boot入门第二天:一个基于Spring Boot的Web应用,使用了Spring Data JPA和Freemarker。详解编程语言
- Spring Boot系列二 Spring @Async异步线程池用法总结详解编程语言
- Spring Boot(十二):spring boot如何测试打包部署详解编程语言
- Spring Boot(五):spring data jpa的使用详解编程语言
- Spring Boot(二):web综合开发详解编程语言
- Hibernate+Spring+Struts扩展Struts