软件框架技术3(SpringMVC)

目录

1.SpringMVC概述

 2.SpringMVC基本使用

2.1maven中web项目的构建

 2.2 SpringMvc开发中 简单注解

2.2.1  @Controller

 2.2.2  @RequestMapping

 2.2.3 @ResponseBody

 3.请求与响应【重点】

3.1请求路径的映射

 3.2 请求参数问题【五种类型参数传递 】

3.2.1发送    普通请求   参数

3.2.2   POJO类型 参数

 3.2.3  嵌套pojo类型

 3.2.4  数组和集合的形式 类型的参数

 3.2.5  json数据参数传递 *****

 4.RESTful风格

 5.Rest 快速开发【重点】

6.拦截器

1.拦截器的概念和作用

 2.拦截器的实现

 3.配置加载拦截器

4.拦截器流程分析

5.配置多个拦截器


1.SpringMVC概述

SpringMvc是一种基于Java实现MVC模型的轻量级web框架

1.在javaEE开发中,系统经典的三层架构包括表现层,业务层,持久层。三层架构中,每一层各司其职,

        表现层(Web层):负责接收客户端请求,并响应客户端结果;

        业务层(Service层):负责处理业务逻辑,与项目息息相关;

        持久层(DAO层):负责与数据库交互,对数据库进行增删改查。

2.SpringMvc 优点:

        1.使用简单,开发便捷(相比Servlet)

        2.灵活性强!

 2.SpringMVC基本使用

2.1maven中web项目的构建

两种构建方式:IDEA中创建Maven Web项目(两种方式)_码农怎么做的博客-CSDN博客_idea创建maven web项目

 2.1.1导入坐标

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
</dependencies>

 2.1.2 配置 tomcat 服务器。

 2.1.3 配置web容器类

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;

//web容器配置类  --类名可以自己定义 但是尽量要见名知意
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
    //加载springmvc配置类,产生springmvc容器(本质还是spring容器)
    protected WebApplicationContext createServletApplicationContext() {
        //初始化WebApplicationContext对象
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        //加载指定配置类
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }

    //设置由springmvc控制器处理的请求映射路径
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    //加载spring配置类
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }
}

 2.2 SpringMvc开发中 简单注解

2.2.1  @Controller

@Controller 类注解   SpringMvc控制器 定义上方 

作用: 设定 SpringMVC的核心控制器 Bean

@Controller
public class UserController {
}

 2.2.2  @RequestMapping

  • 名称:@RequestMapping

  • 类型:方法注解

  • 位置:SpringMVC控制器方法定义上方

  • 作用:设置当前控制器方法请求访问路径

@RequestMapping("/save")
public void save(){
    System.out.println("user save ...");
}

 2.2.3 @ResponseBody

  • 名称:@ResponseBody

  • 类型:方法注解

  • 位置:SpringMVC控制器方法定义上方

  • 作用:设置当前控制器方法响应内容为当前返回值,无需解析

@RequestMapping("/save")
@ResponseBody
public String save(){
    System.out.println("user save ...");
    return "{'info':'springmvc'}";
}

入门程序开发总结(1+N)

  • 一次性工作

    • 创建工程,设置服务器,加载工程

    • 导入坐标

    • 创建web容器启动类,加载SpringMVC配置,并设置SpringMVC请求拦截路径

    • SpringMVC核心配置类(设置配置类,扫描controller包,加载Controller控制器bean)

  • 多次工作

    • 定义处理请求的控制器类

    • 定义处理请求的控制器方法,并配置映射路径(@RequestMapping)与返回json数据(@ResponseBody)

 还有一些细节问题

 3.请求与响应【重点】

3.1请求路径的映射

1.  @RequestMapping  注解 

  • 名称:@RequestMapping

  • 类型:==方法注解 类注解==

  • 位置:SpringMVC控制器方法定义上方

  • 作用:设置当前控制器方法请求访问路径,如果设置在类上统一设置当前控制器方法请求访问路径前缀

@Controller
//类上方配置的请求映射与方法上面配置的请求映射连接在一起,形成完整的请求映射路径
@RequestMapping("/user")
public class UserController {
    //请求路径映射
    @RequestMapping("/save") //此时save方法的访问路径是:/user/save
    @ResponseBody
    public String save(){
        System.out.println("user save ...");
        return "{'module':'user save'}";
    }
}

 3.2 请求参数问题【五种类型参数传递 】

3.2.1发送    普通请求   参数


@Controller
@RequestMapping("/user")
public class UserController {
    //设置映射路径为/save,即外部访问路径
    @RequestMapping("/save")
    //设置当前操作返回结果为指定json数据(本质上是一个字符串信息)
    @ResponseBody
    public String save(String username,Integer age){
        System.out.println("user save ...");
        System.out.println("姓名:" + username);
        System.out.println("年龄:" + age);
        return "{'info':'usersave'}";
    }
}

 当我们 发送 get请求 时,不会出现中文乱码问题 ,

 发送 post 请求 时,就会出现中文乱码问题

  get请求 出现中文乱码 就是这种原因

  • 问题:如果同学们使用了tomcat插件传递的参数是中文试试,你们会发现接收到的参数出现了中文乱码问题。

  • 原因:tomcat 8.5版本之后GET请求就不再出现中文乱码问题,但是我们使用的是tomcat7插件,所以会出现GET请求中文乱码问题。

  • 解决:在pom.xml添加tomcat7插件处配置UTF-8字符集,解决GET请求中文乱码问题。

<build>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>80</port><!--tomcat端口号-->
          <path>/</path> <!--虚拟目录-->
          <uriEncoding>UTF-8</uriEncoding><!--访问路径编解码字符集-->
        </configuration>
      </plugin>
    </plugins>
  </build>

 post 普通 请求 解决中文乱码问题

 在配置文件  ServletContainerslnitConfig 写几行代码

//    乱码处理
    @Override
    protected Filter[] getServletFilters() {
//        return super.getServletFilters();
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        return new Filter[]{filter};
    }

3.2.2   POJO类型 参数

1.实体类

public class User {
    private String name;
    private Integer age;

    public User() {
    }

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

 2.请求访问路径:

//    对象 方法接收
    @RequestMapping("/pojoParam")
    @ResponseBody
    public String pojoParam(User user){
        System.out.println("姓名:" + user.getName());
        System.out.println("年龄:" + user.getAge());
        System.out.println(user);
        return "{pojo : user}";
    }

 3.前端模拟访问 

 4.打印结果 

这里有一个注意点: 请求参数key的名称要和POJO中属性的名称一致,否则无法封装。

 3.2.3  嵌套pojo类型

1.实体类:

public class Address {
    private String province;
    private String city;

    //getset toString 略
}

public class User {
    private String username;
    private int age;
    private Address address;
    //get set toString  略
}

2.后端接收

@RequestMapping("/nestPojoParam")
    @ResponseBody
    public String nestPojoParam(User user){
        System.out.println("姓名:" +user.getUsername());
        System.out.println("年龄:" + user.getAge() + "城市:" + user.getAddress().getCity());
        return "{'nestPojoParam':'success'}";
    }

3.模拟发送数据

 

 3.2.4  数组和集合的形式 类型的参数

1.数组类型的参数:请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型即可接收参数

请求的格式:

 后端对应的方法

//    数组形式 接收  传递过来的
    @RequestMapping("/arrayParam")
    @ResponseBody
    public String arrayParam(String[] likes){
//        遍历数组
        System.out.println(Arrays.toString(likes));
        return "{arrayParam : success}";
    }

注意:这里 likes 一定要对应 不然接收不到

上边是 数组形式 接收  ,下面是 用 集合形式接收

2.集合 形式 接收 请求 参数: 

 集合保存普通参数:请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系

 @RequestMapping("/listParam")
    @ResponseBody
    public String listParam(@RequestParam List<String> likes){
        System.out.println(likes);
        return "{'listParam':'success'}";
    }

 3.2.5  json数据参数传递 *****

导入坐标

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>

1.传递json 普通数组:

 注解:

@EnableWebMvc 注解 

  • 名称:@EnableWebMvc

  • 类型:==配置类注解==

  • 位置:SpringMVC配置类定义上方

  • 作用:开启SpringMVC多项辅助功能

@Configuration
@ComponentScan("com.itheima.controller")
@EnableWebMvc//开启json数据类型 自动转换
public class SpringMvcConfig {
}

 @RequestBody 注解

  • 名称:@RequestBody

  • 类型:==形参注解==

  • 位置:SpringMVC控制器方法形参定义前面

  • 作用:将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次

//    json 数组格式
    @RequestMapping("/listParamForJsonArr")
    @ResponseBody
    public String listParamForJsonArr(@RequestBody List<String> likes){
        System.out.println(likes);
        return "'listParamForJsonArr':'success'";
    }

 2.传递json 对象 格式

//    pojoForJson
    @RequestMapping("/pojoParamForJson")
    @ResponseBody
    public String pojoParamForJson(@RequestBody User user){
        System.out.println("姓名:" + user.getUsername());
        System.out.println("年龄:" + user.getAge());
        System.out.println("省份:" + user.getAddress().getProvince());
        System.out.println("省份:" + user.getAddress().getCity());
        return "'pojoParamForJson':'success'";
    }

 3.传递 数组 对象 格式 

//    解析 数组 对象格式
    @RequestMapping("/listPojoForJson")
    @ResponseBody
    public String listPojoForJson(@RequestBody List<User> users){
        System.out.println(users);
        return "'listPojoForJson':'success'";
    }

 **********************

@RequestBody与@RequestParam区别

  • 区别

  • @RequestParam用于接收url地址传参,表单传参【application/x-www-form-urlencoded】

  • @RequestBody用于接收json数据【application/json】

  • 应用 后期开发中,发送json格式数据为主,@RequestBody应用较广 如果发送非json格式数据,选用@RequestParam接收请求参数

 还有一些细节点,日期传递等等 日后要不断学习

 4.RESTful风格

 概述:RESTful风格  是一种 约定 而不是 规范 可以被打破 ,


import com.itheima.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
public class UserController {

    // 进行save保存的是来自 post,表示rest风格 的添加操作
    @RequestMapping(value = "/users",method = RequestMethod.POST)
                                  //请求方式=post请求
               // 如果路径匹配 且请求方式匹配就进该处理器方法
    @ResponseBody
    public String save(@RequestBody User user){
        System.out.println("user save:"+user);
        return "{'module':'save'}";
    }
    // 进行delete删除来自  delete请求 表示rest风格的 删除操作
    @RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
    @ResponseBody
    public String delete(@PathVariable("id")Integer id){
        System.out.println("user delete");
        return "{'module':'delete'}";
    }
   // 进行update更新操作的 来自put请求 表示rest风格的 更新操作
    @RequestMapping(value = "/users",method =RequestMethod.PUT )
    @ResponseBody
    public String update(@RequestBody User user){
        System.out.println("user update:"+user);
        return "{'module':'update'}";
    }
   //进行getById查询操作的 来自 get请求,表示rest风格的查询操作
    // http://localhost:8080/users/3/jack
    // 现在我们方法中想要得到的数据在哪? 请求路径上!!!Path
    //                    这个数据是不是变化的数据--变量 variable
    // 我们要接收的数据 来自 路径变化数据
                //  /users/{id}    {设置的一个变量} 接收当前位置的数据
               //  {} 区分了什么是资源 什么是数据
    @RequestMapping(value = "/users/{id}",method = RequestMethod.GET)
                          // id变量名 接收了 /users/后面的数据
                         // 可以这么想象..id=3
    //  @PathVariable()代表着从路径上的哪个接收变量上获取数据
    @ResponseBody
    public String getById(@PathVariable("id")Integer id){
        System.out.println("user getById..."+id);
        return "{'module':'getById'}";
    }

    //进行getById查询操作的 来自 get请求,表示rest风格的查询操作
    @RequestMapping(value = "/users",method = RequestMethod.GET)
    @ResponseBody
    public String getAll(){
        System.out.println("user getAll");
        return "{'module':'getAll'}";
    }
}

 上面这种方式 不是最简单的方式  了解一下 就ok。

注解:介绍:

 1. @PathVariable  注解

  • 名称:@PathVariable

  • 类型:形参注解

  • 位置:SpringMVC控制器方法形参定义前面

  • 作用:绑定路径参数与处理器方法形参间的关系,要求路径参数名与形参名一一对应

 

注意:@RequestBody、@RequestParam、@PathVariable区别和应用

  • 区别 @RequestParam用于接收url地址传参或表单传参 @RequestBody用于接收json数据 @PathVariable用于接收路径参数,使用{参数名称}描述路径参数

  • 应用 后期开发中,发送请求参数超过1个时,以json格式为主,@RequestBody应用较广 如果发送非json格式数据,选用@RequestParam接收请求参数 采用RESTful进行开发,当参数数量较少时,例如1个,可以采用@PathVariable接收请求路径变量,通常用于传递id值

 5.Rest 快速开发【重点】

  • 名称:@GetMapping @PostMapping @PutMapping @DeleteMapping

  • 类型:方法注解

  • 位置:基于SpringMVC的RESTful开发控制器方法定义上方

  • 作用:设置当前控制器方法请求访问路径与请求动作,每种对应一个请求动作,例如@GetMapping对应GET请求

  • 属性: value(默认):请求访问路径

@postMapping 增加;

@DeleteMapping 删除;

@PutMapping 修改;

@GetMapping 查询;

@Controller
@RequestMapping("/users")
public class UserController {

    //设置当前请求方法为POST,表示REST风格中的添加操作
    @PostMapping
    @ResponseBody
    public String save(){
        System.out.println("user save...");
        return "{'module':'user save'}";
    }

    //设置当前请求方法为DELETE,表示REST风格中的删除操作
    //@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同
    @DeleteMapping("/{id}")
    @ResponseBody
    public String delete(@PathVariable Integer id){
        System.out.println("user delete..." + id);
        return "{'module':'user delete'}";
    }

    //设置当前请求方法为PUT,表示REST风格中的修改操作
    @PutMapping
    @ResponseBody
    public String update(@RequestBody User user){
        System.out.println("user update..."+user);
        return "{'module':'user update'}";
    }

    //设置当前请求方法为GET,表示REST风格中的查询操作
    //@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同
    @GetMapping("/{id}")
    @ResponseBody
    public String getById(@PathVariable Integer id){
        System.out.println("user getById..."+id);
        return "{'module':'user getById'}";
    }

    //设置当前请求方法为GET,表示REST风格中的查询操作
    @GetMapping
    @ResponseBody
    public String getAll(){
        System.out.println("user getAll...");
        return "{'module':'user getAll'}";
    }
}

 在Controller类上使用@RestController注解,等同于@Controller与@ResponseBody两个注解组合功能

@RestController
@RequestMapping("/users")
public class UserController {

    //设置当前请求方法为POST,表示REST风格中的添加操作
    @PostMapping
    public String save(){
        System.out.println("user save...");
        return "{'module':'user save'}";
    }

    //设置当前请求方法为DELETE,表示REST风格中的删除操作
    //@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同
    @DeleteMapping("/{id}")
    public String delete(@PathVariable Integer id){
        System.out.println("user delete..." + id);
        return "{'module':'user delete'}";
    }

    //设置当前请求方法为PUT,表示REST风格中的修改操作
    @PutMapping
    public String update(@RequestBody User user){
        System.out.println("user update..."+user);
        return "{'module':'user update'}";
    }

    //设置当前请求方法为GET,表示REST风格中的查询操作
    //@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同
    @GetMapping("/{id}")
    public String getById(@PathVariable Integer id){
        System.out.println("user getById..."+id);
        return "{'module':'user getById'}";
    }

    //设置当前请求方法为GET,表示REST风格中的查询操作
    @GetMapping

    public String getAll(){
        System.out.println("user getAll...");
        return "{'module':'user getAll'}";
    }
}
  • 名称:@RestController

  • 类型:类注解

  • 位置:基于SpringMVC的RESTful开发控制器类定义上方

  • 作用:设置当前控制器类为RESTful风格,等同于@Controller与@ResponseBody两个注解组合功能

6.拦截器

问题1:拦截器拦截的对象是谁?

问题2:拦截器和过滤器有什么区别?

1.拦截器的概念和作用

  • 拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行

  • 作用:

    1. 在指定的方法调用前后执行预先设定的代码

    2. 阻止原始方法的执行

    3. 总结:增强

  • 核心原理:AOP思想

拦截器 和 过滤器 的区别?

  • 归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术

  • 拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强

 

 2.拦截器的实现

 1.定义拦截器:做法:定义一个类,实现HandlerInterceptor接口即可

@Component //注意当前类必须受Spring容器控制
//定义拦截器类,实现HandlerInterceptor接口
public class ProjectInterceptor implements HandlerInterceptor {
    @Override
    //原始方法调用前执行的内容
    //返回值类型可以拦截控制的执行,true放行,false终止
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle..."+contentType);
        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...");
    }
}

 3.配置加载拦截器

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    @Autowired
    private ProjectInterceptor projectInterceptor;

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        //配置拦截器
        registry.addInterceptor(projectInterceptor)
            .addPathPatterns("/books","/books/*");
    }
}

 使用标准接口WebMvcConfigurer简化开发(注意:侵入式较强)

@Configuration
@ComponentScan({"com.itheima.controller"})
@EnableWebMvc
//实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {
    @Autowired
    private ProjectInterceptor projectInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //配置多拦截器
        registry.addInterceptor(projectInterceptor)
            .addPathPatterns("/books","/books/*");
    }
}

最好使用第一种

4.拦截器流程分析

 拦截参数

  • 参数

    1. request:请求对象

    2. response:响应对象

    3. handler:被调用的处理器对象,本质上是一个方法对象,对反射技术中的Method对象进行了再包装

  • 返回值 返回值为false,被拦截的处理器将不执行。

5.配置多个拦截器

@Component
public class ProjectInterceptor2 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle...222");
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle...222");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...222");
    }
}

 

@Configuration
@ComponentScan({"com.itheima.controller"})
@EnableWebMvc
//实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {
    @Autowired
    private ProjectInterceptor projectInterceptor;
    @Autowired
    private ProjectInterceptor2 projectInterceptor2;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //配置多拦截器
        registry.addInterceptor(projectInterceptor)
            .addPathPatterns("/books","/books/*");
        registry.addInterceptor(projectInterceptor2)
            .addPathPatterns("/books","/books/*");
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

華同学.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值