我是靠谱客的博主 笑点低大船,这篇文章主要介绍springboot实现登录功能和拦截器功能实例功能需求:补充:请求转发与请求重定向的区别,现在分享给大家,希望可以做个参考。

功能需求:

    springboot登陆页面进行登陆验证,并完成登陆跳转。错误的账户提示用户名密码错误,正确的账户跳转到index页面。 

同时加上登陆拦截器,对于错误的账户不允许直接访问index页面。

一  登陆验证 

实现输入正确的用户名密码直接进入index页面,输入错误提示用户名密码错误。

  1. 要实现登录,我们需要先编写一个登录的controller类:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.example.demo.controller; import org.springframework.stereotype.Controller; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpSession; import java.util.Map; @Controller public class LoginController { @RequestMapping("login") public String tologin() { return "login"; } @PostMapping(value="/login") public String login(@RequestParam("username") String username, @RequestParam("password") String password, Map<String,Object> map, HttpSession session){ //验证用户名和密码,输入正确,跳转到index if(!StringUtils.isEmpty(username)&&"lss".equals(password)){ session.setAttribute("userName",username); System.out.println("username===" + username); return "redirect:/index"; } else //输入错误,清空session,提示用户名密码错误 { session.invalidate(); map.put("msg","用户名密码错误"); return "login"; } } @RequestMapping("index") public String goIndex(Map<String,Object> map) { map.put("name","lishanshan"); map.put("age",29); map.put("sex","女"); return "index"; } }

说明:

(1) 跳转页面时使用  return ”redirect:/ index“,而不是 return ”index“ .

 return ”redirect:/ index“,会直接调用controller,  return ”index“ 只会访问目录下的文件

2. 登陆页面 login.html

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>首页</title> </head> <body> <form th:action="@{/login}" method="post"> <!-- 取值替换原来默认的值--> <h1>Please sign in</h1> <p style="color:#ff0000" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p> <label>Username</label> <input type="text" name="username" placeholder="Username" required="" autofocus=""> <label>Password</label> <input type="password" name="password" placeholder="Password" required=""> <button type="submit" >Sign in</button> </form> </body>

说明:

(1)action 配置为th:action="@{/login}" method="post"

添加th:action,告诉模板,我们要跳转的请求是/login,而且是post请求的;

3.简单index页面

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Title</title> </head> <body> <h1>注册成功</h1> 姓名:<spn th:text="${name}"></spn> 年龄:<spn th:text="${age}"></spn> 性别:<spn th:text="${sex}"></spn> </body> </html>

4. properties配置

复制代码
1
2
server.port=8002 spring.thymeleaf.cache=false

说明:为了开发方便,我们还可以将application.properties中添加一个 禁用缓存的参数: spring.thymeleaf.cache=fasle ,这样html页面有改动的时候,我们只需要用快捷键crtl+F9或者点击如图的编译按钮,重新编译下就可以在页面看结果,而不需要再次启动Tomcat服务了

二. 配置拦截器

我们在不输入用户名密码的时候,在地址栏里直接输入

http://localhost:8002/index也能直接访问地址。这是不允许的。所以需要配置拦截器,当用户密码不正确的时候,页面直接跳转到登陆页面,并显示无权限访问。

1.注册拦截器

新建类  webConfigurer  

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.example.demo.configure; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfigurer implements WebMvcConfigurer { // 这个方法是用来配置静态资源的,比如html,js,css,等等 @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); WebMvcConfigurer.super.addResourceHandlers(registry); } // 这个方法用来注册拦截器,我们自己写好的拦截器需要通过这里添加注册才能生效 @Override public void addInterceptors(InterceptorRegistry registry) { // addPathPatterns("/**") 表示拦截所有的请求, // excludePathPatterns("/login", "/register") 表示除了登陆与注册之外,因为登陆注册不需要登陆也可以访问 registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/login"); WebMvcConfigurer.super.addInterceptors(registry); } //设置默认页面 @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("forward:/login"); //设置优先级 当请求地址有重复的时候 执行优先级最高的 registry.setOrder(Ordered.HIGHEST_PRECEDENCE); WebMvcConfigurer.super.addViewControllers(registry); } }

 

2.拦截器

实现 HandlerInterceptor 

三个方法分别是

  • 1.preHandle:在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制、权限校验等处理;
  • 2.postHandle:在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回ModelAndView,但未进行页面渲染),有机会修改ModelAndView (这个博主就基本不怎么用了);
  • 3.afterCompletion:在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面);
    复制代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    package com.example.demo.configure; import org.springframework.lang.Nullable; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; @Component public class LoginInterceptor implements HandlerInterceptor { //这个方法是在访问接口之前执行的,我们只需要在这里写验证登陆状态的业务逻辑,就可以在用户调用指定接口之前验证登陆状态了 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException, ServletException { //每一个项目对于登陆的实现逻辑都有所区别,我这里使用最简单的Session提取User来验证登陆。 HttpSession session = request.getSession(); //这里的User是登陆时放入session的 //如果session中没有user,表示没登陆 Object user = request.getSession().getAttribute("userName"); System.out.println("preHandle----" + user + " ::: " + request.getRequestURL()); if (user == null) { request.setAttribute("msg","无权限请先登录"); // 获取request返回页面到登录页 request.getRequestDispatcher("/login").forward(request, response); //response.sendRedirect("/login"); return false; } else { //如果session里有user,表示该用户已经登陆,放行,用户即可继续调用自己需要的接口 System.out.println("进入拦截器......"); System.out.println(request.getRequestURL()); return true; } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } }

    上边配置的session需要取值才能做判断,那么我们需要在loginController中设置这个session值,以让它生效: session.setAttribute("userName",username);

补充:请求转发与请求重定向的区别

请求重定向和转发

1、请求重定向:浏览器的行为(通过响应对象HttpServletResponse来执行)

特点:可以重新定向访问其他Web应用下的资源

浏览器发出了2次请求,得到了2次响应

地址栏地址会变,跳转到要求指定的Servlet

代码演示:

//请求重定向方式一:

复制代码
1
2
3
4
5
public void sent1(HttpServletResponse response) { response.setStatus(302); response.setHeader("Location", "/ServletStudy/servlet/ServletDemo2"); //这个地址是要求浏览器重新访问的。 }

//请求重定向方式二:

复制代码
1
2
3
4
5
6
7
8
public void send2(HttpServletRequest request,HttpServletResponse response) throws IOException { //服务器向访问的浏览器的请求中添加属性,当被请求重定向后,在新的Servlet中不能得到添加的属性。 //因为请求重定向后的请求request对象不懂,这就是request的生命周期。 request.setAttribute("name", "zhangsan"); //与方式一实现的原理相同,较为常用 response.sendRedirect("/ServletStudy/servlet/ServletDemo2"); }

2、请求转发:服务器的行为(转发的瞬间是一个ServletRequest的生命周期)

特点:转发只能发生在当前Web应用下

浏览器发出了1次请求,得到了1次响应

(源组件和目标组件共享request和response中的数据)

地址栏地址不会发生变化。

应用:

(1)可以利用request的域对象的特点,由源组件向其中存放写数据。

(2)可以让用户访问到存放在WEB-INF目录中的目标资源

代码演示:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//请求转发 public void send3(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{ //在请求转发之前进行属性添加,在新的Servlet资源中能获取这个属性 request.setAttribute("name", "zhangsan"); //获取当前Servlet资源的转发器对象RequestDispatcher,传入当前应用的下要访问的那个Servlet资源 RequestDispatcher rd = getServletContext() .getRequestDispatcher("/servlet/ServletDemo2"); //注意:传入的要访问的Servlet资源的地址中/代表的就是当前应用,所以就可以访问当前应用中WEB-INF中的信息 rd = getServletContext() .getRequestDispatcher("/WEB-INF/form.html"); //也可以通过request得到转发器对象,用request得到的转发器在传入路径时,可以传入相对路径,不用加/ rd = request.getRequestDispatcher("/servlet/ServletDemo2"); //这里传入的路径地址:相对去被转发地址不同地方 //被转发地址: http://localhost:8080/ServletStudy/servlet/ServletDemo1 //转发地址: http://localhost:8080/ServletStudy/servlet/ServletDemo2 //所以填写相对资源地址:ServletDemo2 rd = request.getRequestDispatcher("ServletDemo2"); //调用转发器的forward()方法,进行请求转发 rd.forward(request, response); }

3.RequestDispatcher中forward()转发和include()包含的区别

forword()转发:源组件<--->头+体

源组件转向目标组件,由目标组件显示响应正文结果(只有目标的响应)

转发前,容器会清空response对象的缓存,源组件的任何页面输出都无效,也就是会清空源组件的体

转发前不要刷新或关闭response的流

 

include()包含:

源组件包含目标组件,由源组件显示响应正文结果(还会把目标的响应结果包含进来)

包含前,容器会清空目标组件设置的响应头信息,目标组件所有设置的所有头都无效。

代码演示:

//RequestDispatch转发器中的:forward()和include()方法的区别

/*forword()转发:

源组件转向目标组件,由目标组件显示响应结果(只有目标的响应)

转发前,容器会清空response对象的缓存,源组件的任何页面输出都无效。

转发前不要刷新或关闭response的流

 

include()包含:

源组件包含目标组件,由源组件显示响应结果(还会把目标的响应结果包含进来)

包含前,容器会清空目标组件设置的响应头信息,目标组件所有设置的所有头都无效*/

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class ServletDemo3 extends HttpServlet { //当做源组件 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { forwardTest(request, response); } public void forwardTest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { //response.setHeader("Refresh", "2"); OutputStream out = response.getOutputStream(); System.out.println("转发前向控制台输出"); out.write("转发前向页面输出".getBytes()); RequestDispatcher rd = request.getRequestDispatcher("ServletDemo4"); rd.forward(request, response); System.out.println("转发后向控制台输出"); out.write("转发后向页面输出".getBytes()); } public class ServletDemo4 extends HttpServlet { //当做目标组件 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("Refresh", "2"); response.getOutputStream().write("目标组件".getBytes()); }

4.ServletContext和ServletRequest都能得到RequestDispatcher区别

(1)ServletContext

RequestDispatcher getRequestDispatcher(String path):path必须以"/"开头,代表当前的应用。这种写法,叫做绝对路径写法。

(2)ServletRequest

RequestDispatcher getRequestDispatcher(String path):

path可以以"/"开头:代表当前的应用。这种写法,叫做绝对路径写法。

也可以不以"/"开头:代表相对路径。

 

5.各种URL的写法:绝对路径和相对路径,建议大家使用绝对路径

绝对路径:如:/day05  地址前加了/就是一个绝对路径

原则:要不要加应用名称,看地址为谁服务的?

如果是给服务器用的,就不用加/MyApp,"/"代表的是当前应用。

如果是给客户端用的,要加上"/MyApp","/"代表的是要访问的服务器的URL地址(域名+端口),

getRequestDispatcher(String path):

path是一个路径。 不要加"/MyApp",只需要"/"即可

form action="url":要加"/MyApp"

a href="url":要加"/MyApp"

img src="url":要加"/MyApp"

link href="url":要加"/MyApp"

script src="url":要加"/MyApp"

302+Location="url":要加"/MyApp"

最后

以上就是笑点低大船最近收集整理的关于springboot实现登录功能和拦截器功能实例功能需求:补充:请求转发与请求重定向的区别的全部内容,更多相关springboot实现登录功能和拦截器功能实例功能需求:补充:请求转发与请求重定向内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(77)

评论列表共有 0 条评论

立即
投稿
返回
顶部