SpringMVC

SpringMVC概述

什么是SpringMvc

SpringMVC是一个Spring框架支持下衍生出来的框架

用途是简化控制层的操作,这里的控制层指的就是Servlet

其中MVC分别代表

M:Model(数据模型) V:View(视图) C:Controller(控制器)

SpringMVC框架主要解决的是V和C的交互问题

当前有很多解决V和C交互问题的框架,除SpringMvc之外还有Struts2,JFinal等

SpringMvc核心执行流程图

DispatcherServlet:前端控制器,用于接收所有请求

HandlerMapping:用于配置请求路径与Controller组件对应关系的

Controller:控制器,由使用框架的程序员编写的处理请求的组件

ModelAndView:Controller处理请求后的结果,由数据和视图名称组成

ViewResolver:视图解析器,根据视图名称,确定要返回的视图
在这里插入图片描述
1.浏览器发出Spring mvc请求,请求交给前端控制器DispatcherServlet处理
2.控制器通过HandlerMapping维护的请求和Controller映射信息,找到对应的Controller组件处理请求
3.执行Controller组件约定方法处理请求,在约定方法中可以调用Service和DAO等组件完成数据操作,约定方法可以返回一个ModelAndView对象,封装了模型数据和视图名称信息
4.控制器接收ModelAndView之后调用ViewResolver组件,定位View的JSP并传递Model信息,生成响应界面结果

使用SpringMVC返回视图

步骤1:
SpringMvc返回视图,默认需要Thymeleaf的

所以要添加Thymeleaf的依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

步骤2:

要想返回视图模板,首先要有视图模板

之前我们在static文件夹下创建的页面不是视图模板

我们必须将视图模板保存在templates文件夹下,它就在static文件夹的旁边

在templates文件夹下创建一个model.html页面

代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>这是视图模板中的内容!</h2>
    <p>好好学习~</p>
</body>
</html>

步骤3:
在控制器中编写代码,显示我们编写的模板
代码如下

//GetMapping只能处理get请求
    @GetMapping("/view")
    public ModelAndView show(){
        System.out.println("运行show方法");
        //SpringBoot约定了当使用Thymeleaf返回视图时
        //返回的信息会自动定位在
        //src/main/resources/templates/文件夹中
        //并且会在返回的信息后自动加.html
        //当程序返回model时,内部实际制定的模板就是
        //src/main/resources/templates/model.html
        return new ModelAndView("model");
    }

然后启动服务,在浏览器地址栏输入路径后访问即可

在SpringMvc中使用HttpServletRequest对象

在控制器中获得Request对象编写代码如下

@PostMapping("/handle_reg")
@ResponseBody
public String handleReg(User user,
        HttpServletRequest request){
    //使用request对象获取客户端的ip地址
    System.out.println("客户端ip:"
            +request.getRemoteAddr());
    System.out.println(user);
    return  "OK";
}

在SpringMvc中获得url中的get参数

在web编程过程中,通常使用url地址传递一些信息例如

http://localhost:8080/demo?id=100&name=tom

如果想在控制器中获得id的值和name的值就需要编写如下代码

@GetMapping("/demo")
@ResponseBody
public String getUrl(int id,String name){
    System.out.println("id:"+id+",name:"+name);
    return "id:"+id+",name:"+name;
}

如果在传递过程中,出现巧合:参数名是java的关键字

那么就没有办法直接获得传递的值了

例如

http://localhost:8080/demo?id=100&return=tom

需要使用@RequestParam注解来标记参数,代码如下

 @GetMapping("/demo")
    @ResponseBody
    public String getUrl(int id,
           @RequestParam("return") String name){
        System.out.println("id:"+id+",name:"+name);
        return "id:"+id+",name:"+name;
    }

SpringMvc中使用Session

HttpSession简称session
是浏览器的一次会话
如果将信息保存到session中
那么只要不关闭浏览器,不超时(默认30分钟),session中的信息就不会丢失
特别适合保存用户的登录状态,session中的信息保存在服务器内存中

SpringMvc控制器中获得Session

创建一个userinfo.html页面
代码如下

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>当前用户:</h1>
<p th:text="${user}"></p>
</body>
</html>

创建一个HomeServlet,编写两个方法,分别向Session对象保存数据和获取数据
代码如下

@RestController
public class HomeController {
    //向session中保存信息的方法!
    @GetMapping("/session")
    public String show(HttpSession session){
        session.setAttribute("user","Tom");
        return "session saved!";
    }
    //显示Session中信息的方法
    @GetMapping("/showsession")
    public ModelAndView showSession(
            HttpSession session, ModelMap map){
        String name=(String)session
                .getAttribute("user");
        map.put("user",name);
        return new ModelAndView("userinfo");
    }
}

SpringMVC的拦截器

什么是拦截器
拦截器指的是SpringMvc框架中的组件

拦截器(Interceptor)是在请求到达控制器方法之前或之后能够运行指定代码的机制,这个机制允许阻止请求访问指定的控制器方法

为什么需要拦截器img

编写拦截器可以统一检查或处理请求中的一些指标
比如需要登录时,拦截器可以检查session中有没有登录信息
如果没有就跳转到登录也页面
将判断的代码编写在拦截器中能够减少控制器中的代码冗余

怎么使用拦截器

下面我们来使用一下拦截器的基本功能

步骤1:

我们先来创建一个拦截器

所有拦截器类都统一实现HandlerInterceptor接口

我们新建拦截器包interceptor,在包中新建类

DemoInterceptor类代码如下

public class DemoInterceptor
        implements HandlerInterceptor {
    // 在运行控制器方法之前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        //这个方法的返回值 返回true表示放行,允许访问控制方法
        //返回false表示阻止访问控制器方法
        return true;
    }
    //在运行控制方法之后
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }
    //视图处理器处理完毕以后
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}

步骤2:
在配置类中配置拦截器的拦截规则
SpringBoot项目配置类就是带有main方法的类

代码修改如下

@SpringBootApplication
@EnableWebMvc
public class MvcApplication
        implements WebMvcConfigurer {public static void main(String[] args) {
        SpringApplication.run(MvcApplication.class, args);
    }@Override
    public void addInterceptors(
            InterceptorRegistry registry) {
        //这个方法用于设置拦截器的拦截规则
        //registry对象就是设置拦截规则的对象
        registry.addInterceptor(new DemoInterceptor())
                .addPathPatterns("/showsession");
    }
}

重启服务,访问/showsession观察拦截器的运行

拦截器的运行流程图img

使用拦截器实现登录权限管理

步骤1:再次创建一个拦截器,来实现登录权限管理
AccessInterceptor,代码如下

public class AccessInterceptor
                implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //从session中获得用户信息
        String name=(String)request
                .getSession().getAttribute("user");
        //判断用户信息是否为空
        if(name==null) {
            //如果为空跳转到登录页面
            //显示登录页面的控制器方法的路径是:
            //localhost:8080/login
            System.out.println("没有登录!请登录");
            String path=request.getContextPath()+"/login";
            response.sendRedirect(path);
            return false;//阻止后面的访问
        }
        //如果不为空,放行
        System.out.println("已经登录,放行!");
        return true;
    }
}

步骤2:
配置拦截器

@Override
    public void addInterceptors(
            InterceptorRegistry registry) {
        //这个方法用于设置拦截器的拦截规则
        //registry对象就是设置拦截规则的对象
        registry.addInterceptor(new DemoInterceptor())
                .addPathPatterns("/showsession");
        registry.addInterceptor(new AccessInterceptor())
                .addPathPatterns("/showsession");
    }

一个拦截器可以在多个路径上生效,配置方法就是在addPathPatterns方法中编写多个拦截路径即可

registry.addInterceptor(new AccessInterceptor())
                .addPathPatterns(
                        "/showsession",
                        "/list",
                        "/cart",
                        "/message"
                        );

如果一个项目有太多需要拦截验证登录的路径,如果都写在上面太麻烦了

我们可以设计一个前置路径,这个路径下的所有请求都需要进入拦截器

代码如下

registry.addInterceptor(new AccessInterceptor())
                .addPathPatterns(
                        "/user/*",
                        "/home/*",
                        "/vrd/**"
                        );

这个通配的规则一个*表示这个路径下的所有直接请求 例如

/user/list,/user/chong 等 但是不能拦截这样的路径 /user/demo/hello

如果想拦截上来多层的路径就需要写两个*

上面的通配编写出来以后,能够将符合这个通配的所有请求都拦截

但是如果符合通配的所以请求中有个别请求不需要拦截

就需要单独设置例外

registry.addInterceptor(new AccessInterceptor())
        .addPathPatterns(
                "/user/*",
                "/home/*",
                "/vrd/**")
        .excludePathPatterns(
                "/user/chong",
                "/home/xxx"
            );
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值