SpringMVC

SpringMVC的基本流程:

浏览器发送请求,如请求地址符合前端控制器的url-pattern,该请求就会被前端控制器DispatcherServlet进行处理,前端控制器会读取SpringMVC的核心配置文件,通过扫描组件的方式找到控制器,将请求地址和控制器中的@RequestMapping(请求映射)的value属性值进行匹配,如果匹配成功,该注解所标识的控制器方法就是处理请求的方法,处理请求的方法需要放回一个字符串类型的视图名称,视图名称通过被视图解析器进行解析,加上前缀和后缀之后组成视图的路径,通过Thymeleaf对视图进行渲染,最终转发的视图所对应的页面。

 

Dispatcher翻译为调度

 

@RequestMapping注解

  翻译为请求映射,作用是将请求和处理请求的处理器进行联系起来,建立映射关系

SpringMVC接收到指定的请求,就会来找到映射关系中对应的控制器中的方法进行处理这个请求

 

同一个路径只能有一个@RequestMapping进行映射

 

@RequestMapping注解可以使用的范围:类和方法上

作用的类上面:设置映射请求的请求路径的初始信息

例如:

@Controller

@RequestMapping(“Hello”)

Public class Controller{

   @ReuqestMapping(“/”)

   Public String test(){

Return “test”;

}

}

 

就需要使用 http://ip:port/工程路径/Hello/  这个请求才能被test方法进行处理,需要先处理初始信息,在处理具体信息

 

作用在方法上面:设置映射请求请求的具体信息

 

@RequestMapping中的属性值:

 

 

 

 

其中value属性的值必须进行设置

 

@RequestMapping中的Method属性值的含义:通过请求方式进行映射,如POST和GET请求等

如果没有进行设置method中的属性值,表示只要当地址匹配(也就是和value的属性值相匹配,就可以访问,不管是通过那种请求方式进行访问)

 

示例代码如下:

控制器中的代码

 

 

 

 

Index.html中的代码:

 

 

 

 

运行结果:

通过Get请求进行访问的时候,截图如下:

 

 

 

 

成功

 

通过POST请求进行访问的时候:

 

 

 

 

Method中的属性值不相匹配,所以不能访问。

 

 

@RequestMapping的派生类注解:

@GetMapping:就相当于将@Reuqestmapping的Method属性值设置为Get请求

@PostMapping:就相当于在@RequestMapping中的method中的属性值设置为Post请求

@PutMapping:就相当于将@ReuqestMapping中的Method中的属性值设置为Put请求

等。。。

 

 

 

@RequestMapping注解中的params属性值:

   表示通过请求参数的方式进行匹配,只有当参数完全匹配的时候,才能进行访问页面

 

 

 

 

实例代码如下:

通过form表单进行提交,请求类型为get

 

 

 

Controller中的代码如下:

 

 

 

 

通过表单进行访问的结果是:

 

成功

 

 

 

 

通过超链接进行访问(请求参数中没有username)

 

 

 

(提示:通过thymeleaf进行添加参数的方法)

th:href="@{/test.html(username='xiaowang',password=123456)}"

 

 

SpringMVC中的ant风格:

 

 

 

 

一个?表示任意的单个字符

一个*表示任意的0个或者多个字符

两个**表示任意的一层或者多层目录

 

 

@RequestParam注解的属性和作用:

属性:

1、value属性:作用:将请求参数中的哪一项和controller中的形参进行创建映射关系

2、Required属性:作用:默认是true,表示只有当这个请求参数存在的时候才会继续,如果不存在切没有设置defaultvalue就会报错

3、Defaultvalue属性:作用:设置默认值,当请求为null和空字符串的时候进行使用。

 

 

 

 

@RequestHeader注解的作用和属性:

作用:用于获取请求头中的信息

属性:

1、value属性:需要的请求头中的信息键值对中的key

2、Required属性:设置这个需要的请求头信息是否是必须的存在

3、Defaultvalue属性:设置默认值,当请求头中没有对应value中的key时,就会使用默认值

 

@CookieValue注解的作用和属性:

作用:获取value属性中对应的cookie的值

属性:

1、value属性:cookie对象的key部分

2、Required属性:设置是否是必须含有的cookie

3、Defaultvalue属性:设置默认值,设置当value属性对象的cookie属性不存在时使用的值。

 

 

 

SpringMVC中将请求参数中的信息封装成一个Bean对象的代码实现:

 

注意:StringMVC中通过请求参数创建相应的Bean对象的时候,请求中的参数的name需要和Bean中的属性名相对应(和将数据库中的数据进行取出在创建对象注意事项相同)

 

这是在表单中的代码:

 

 

 

 

 

这是在controller控制器中的代码

 

 

 

 

 

这是Bean对象中的代码

 

 

 

StringMVC中解决中文编码问题:

可以通过过滤器将请求先设置编码集,再由dispatcherServlet进行获取请求。

 

代码如下:

 

 

 

 

注意:因为SpringMVC中没有使用JSP,所以没有page域对象,只有三个域对象,分别是:request域对象、session域对象、application域对象。

 

 

通过SpringMVC将数据共享到request域对象中:

第一种方式:

通过Servlet原生的API进行共享

代码如下:

 

 

 

Controller类中的方法的参数为HttpServletRequest类型的话,会将这个请求自动进行赋值。

 

 

第二种方式:

通过ModelAndView将数据共享到request域对象中

代码如下:

 

 

 

 

 

ModelAndView的作用:可以将这个类名进行分解,分为两个:

Model

   作用:将数据进行共享,通过addObject()方法进行添加数据。

View

   作用:设置请求转发的视图名称(什么是视图名称,也就是将一个页面的路径和后缀进行删除后单纯页面的名称)

 

需要注意的是:

如果是通过ModelAndView进行共享数据,就必须将ModelAndView这个类型作为这个方法的返回值

 

原因:因为是将数据保存在request域对象中,只有通过请求转发的方式才能获取到当前request域对象中的数据,由于在ModelAndView对象中进行设置了视图的名称,因此可以通过ModelAndView进行请求的转发(也就是说Thymeleaf视图解析器可以将ModelAndView中的视图名称进行解析获取页面),如果是直接返回一个视图名称的话,这个请求中的数据就不能在转发之后进行读取。

 

 

 

 

  第三种方式:

通过Model的方式将数据共享到request域对象中

代码如下:

 

 

 

 

 

使用这种方法最后还是会使用到ModelAndView对象,大致是这样的流程,先自动化将参数model进行赋值,在通过addArrtibute方法进行保存数据,最后底层会创建一个ModelAndView对象,将这个方法的返回值String作为视图名称,将Modle作为ModelAndView中的Model,在将这个ModelAndView通过Thymeleaf视图解析器进行解析。

 

第四种方式:

通过Map进行共享数据

代码如下:

 

 

 

 

 

 

第五种方式:

通过ModelMap进行共享数据

代码如下:

 

 

 

 

MapModelMapModel之间的关系:

 

 

 

 

 

 

如图

ModelMap继承了LinkedHashMap

LinkedHashMap实现了接口Map

 

 

 

 

 

如图可以看出Modle这个接口是通过Map进行存储数据的

 

因此,本质上ModelMapModelMap可以说是使用的同一个类进行操作的

 

通过反射机制中的getClass方法可以得出结论:

统一是通过

 

 

 

这个类进行操作的。

 

session域对象中共享数据:

推荐使用Servlet原生API进行共享session域数据

代码如下:

 

 

将数据共享到session域对象中的方式推荐是用原生的ServletAPI的方式,添加参数HttpSession对象进行共享

 

 

Application上下文对象中进行共享数据:

通过使用HttpServletRequest对象进行获取上下文对象进行保存数据或者通过HttpSession对象进行获取上下文对象进行保存数据,

代码如下:

 

 

 

 

通过Thymeleaf从域对象中进行取出数据的方法:

 

 

 

 

总结:

向域对象中进行共享数据的方法:

request域对象中进行共享数据:

1、通过使用Servlet原生的API进行共享,使用HttpServletRequest对象进行共享

2、通过使用Spring中的ModelAndView,将数据保存到Model中,在设置视图名称,返回类型必须是ModelAndView

3、通过Model进行保存:传入Model参数,保存数据,返回视图名称(String

4、通过Map进行共享数据:传入Map参数,保存数据,返回视图名称(String

5、通过ModelMap进行共享数据:传入ModelMap参数,保存数据,返回参数名称(String

上述的345种方法底层都是使用的同一个类进行操作的(BindingAWareModelMap这个类)

 

session域对象中进行共享数据:

通过使用Servlet原生API进行共享数据:传入参数HttpSession,保存数据,返回视图名称(String

 

Application域对象中进行共享数据:

通过使用Servlet原生的API进行共享数据:传入request对象(HttpServletRequest)或者SessionHttpSession)对象进行获取ServletContext上下文对象,在进行保存数据,返回视图名称(String

 

 

什么时候视图会被ThymeleafViewResolver进行解析成为要给ThymeleafView视图:

只有当视图名成没有任何前缀的时候,就会被ThymeleafViewReSolver视图解析器进行解析成为一个ThymeleafView视图。(通过ThymeleafViewResolver解析器进行解析后的视图,最终获取到的页面会通过转发的方式进行跳转)

 

 

如果有前缀:

  前缀为:forward:表示转发视图(叫做internalResourceView

  前缀为:redirect:表示重定向视图(叫做RedirectView

 

 

示例代码:

 

 

 

使用转发视图和重定向视图都需要进行两次解析:

第一次解析:将前缀进行去掉,在将去掉后的请求进行相应的操作(如果是请求转发,就是将请求进行再次转发,如果是重定向视图就将请求进行重定向)。

 

第二次解析:在将请求和控制器中的请求映射进行匹配,如果匹配成功,执行控制器中的方法,将返回的视图名称通过thymeleaf视图解析器进行解析,最后返回页面。

 

 

SpringMVC中的视图控制器:

什么时候使用:

  当一个控制器中的方式不用处理请求,只需要设置一个视图名称的时候就可以使用,例如首页就是一个简单的例子。

  通过xml中的视图控制器将映射和页面进行设置:

    

 

 

 

  

注意:如果添加了一个视图控制器之后,在控制器中所有的映射关系都会消失。

如何解决:需要开启mvc中的注解驱动

 

 

 

创建一个jsp视图解析器只能创建两种视图类型:(internalResourceView视图类型和rediaectView视图类型)

 

什么时候创建internalResourceView视图类型:当添加了前缀为forward:或者没有任何前缀(因为没有添加前缀会被我们创建的InternalResourceViewResolver解析器进行解析)的时候创建的视图类型为internalReourceView类型

 

什么时候创建redizectView视图类型:当添加了前缀为redizect:的时候创建的视图类型为redizectView类型

 

 

如何发送put请求和delete请求:

需要创建一个过滤器(HiddenHttpMethodFilter

 

 

 

 

 

 

 

从源码中可以看出,如果想要发送的请求类型为putdelete请求需要满足两个条件:

  第一个条件:必须是post请求

  第二个条件:需要有一个参数的name属性为_method,它的值必须是putdeletepatch请求

 

 

请求为putdelete类型的代码如下:

 

需要注意:因为HiddenHttpMethodFilter中将请求中的_method这个参数进行获取了,如果将处理编码的过滤器放在他的后面就没有任何的作用,需要将处理编码的过滤器放在处理请求的过滤器之前

 

通过Thymeleaf语法将域对象中的集合进行遍历:

语法如下:

 

 

 

 

通过th:each=” 每一个元素的引用 ” :集合    (语法和foreach类似)

 

通过Thymeleaf将请求参数拼接到地址中的方法:

 

 

 

 

 

 

 

Thymeleaf@{}是用来解析地址的

 

注意:不是直接创建的标签,如果需要进行绑定事件,需要使用on进行绑定:

实例代码:

 

 

 

 

如图:上面的iddeleteHref的标签就是通过Thymeleaf语法进行遍历间接创建的标签,如果需要进行绑定单机事件,就需要使用on的方式进行绑定事件,如果使用原来的方式进行绑定事件,事件不会生效。

 

 

如何处理静态资源:

首先,静态资源是在我们后面进行添加的,需要重新进行在maven中打war包,其次,在重新进行打包之后,因为Dispatcher前端控制器的映射和tomcat服务器中的web.Xml文件中的DefalutServlet程序冲突,就近原则,就会选择Dispatcher进行处理所有的请求,结果就导致不能将静态资源进行加载,需要在Spring.xml文件中将DefaultServlet程序进行开启,开启的方法:(<mvc:default-servlet-handler/>)注意,如果进行开启之后,需要再加上注解驱动,如果不加上注解驱动,之前的映射关系会全部失效,并且所有的请求都会通过defaultServlet程序进行处理,结果就是什么都不能使用,只能加载静态资源。注解驱动的代码(<mvc:annotation-driven

 

Dispatcher前端控制器和DefaultServlet程序处理的先后顺序:

先通过Dispatcher前端控制器进行处理,如果不能进行处理,在通过DefaultServlet程序进行处理

 

 

 

HttpMessageConverter(报文信息转化器):

作用:将java对象转化成相应报文,将请求报文转化成java对象

 

HttpMessageConverter中的两个注解和两个类型:

 

两个注解:@RequestBody    @ResponseBody      

两个类型:RequestEntity       ResponseEntity

   

  @RequestBody注解的作用:

        将请求报文转化为java对象

 

实例代码:

    

 

 

 

注意:如果是使用了@RequestBody注解,就必须要提交数据,否则不会得到访问。

 

实例:

 

 

 

 

如果这里没有使用form表单进行提交数据,那么就不会访问到上图中的控制器,达到success界面。反之,则能过进行访问,输出的数据为:

 

也就是进行提交的数据

 

 

 

RequestEntity的作用:

         将请求报文进行封装,在使用的时候需要进行传入该类型的参数,会自动将这个请求中的请求报文进行赋值。(请求报文中包含有请求体和请求头,请求体中的数据只有是通过post请求进行提交的才会有数据,否则为null

       示例代码:

 

 

 

 

 

 

注意:如果是通过上面这个图的方式进行提交信息,请求体中不会存在数据,结果就是null,当通过一个form表单(提交方式为post请求)进行提交数据的时候,请求体中才会存在数据。

         

 

 

  @ResponseBody注解的作用:

 

通过这个注解我们可以很容易的将一个java对象自动转化成为一个json对象

 

      java对象转化为响应体报文

 

实例代码:

 

 

 

 

 

注意:如果添加了@ResponseBody注解之后,返回的就不再是一个视图名称了,而是一个响应体。例如这个的success,如果没有添加注解@ResponseBody,返回的就是一个视图名称,这个视图名称会被Thymeleaf视图解析器进行解析,如果添加了@ResponseBody注解之后,就表示相应体中的数据为success这个字符串

 

 

 

注意:不能直接将一个对象放到响应体中相应给浏览器,需要将这个对象进行转化成JSON字符串类型对象之后,在页面再将JSON字符串类型转化成JSON对象类型进行取出。

 

 

 

如果直接将对象进行相应,就会出错。

 

SpringMVC中,不用我们手动的将对象转化成json字符串的形式,可以通过jackson进行自动转化。

 

通过jacksonjava对象转化成一个json字符串形式的具体操作:

1、通过maven将依赖进行引入

 

 

 

 

2、需要在springMVC的核心配置文件中开启注解驱动(<mvc:annotation-driven/>

3、处理器的方法上需要使用@ResponseBody注解的方式进行表示

4、直接将java对象作为返回值

满足以上给四点之后,就可以讲返回的java对象自动转化成一个json字符串形式

 

 

 

通过springMVC处理ajax请求:

实例代码如下:

 

 

 

 

 

 

 

 

Ajax请求的作用是不刷新页面,进行局部的更新,,其中回调函数中的参数,就代表了响应体中的内容。(如实例中的response参数)

 

 

 

ResponseEntity的作用:

 ResponseEntity用于控制方法的返回值类型,该控制器方法的返回值就是响应到浏览器的响应报文。

 

作用一:(通过ResponseEntity实现文件下载功能)

   示例代码:

 

 

 

设置请求头中的信息是固定的,只有文件的名称可以进行自定义。

创建一个ResponseEntity对象(响应报文)需要三个参数:请求体、请求头、请求响应码

 

 

 

 

作用二:(通过ResponseEntity实现文件的上传)

如果要实现上传功能,需要进行以下操作:

第一:需要添加依赖commons-fileupload这个jar

 

 

 

第二:需要在SpringMVC的核心配置文件中进行添加一个上传解析器,将上传的文件解析成为MultipartFile对象(在创建这个bean的时候,只能通过id进行获取,并且id值的属性需要进行固定,multipartResolver,不能通过类型进行获取),便于通过Spring进行自动赋值获取。

 

 

 

第三:必须是通过post请求进行提交

 

   实例代码:

 

 

 

 

photo文件夹在target

 

 

 

 

文件上传需要注意,如果当两个文件的文件名相同的时候,IO中默认使用的是不进行追加,结果就是会将原先文件中的内容进行覆盖。

 

如何解决文件内容发生覆盖的问题:

可以通过给每一个文件添加一个无法重复的名称进行解决,这里通过使用javautil中的UUID进行解决

 

示例代码:

 

 

 

 

@RestController注解的作用:

他的作用主要是两个:(他是一个类的注解,类似于@Controller注解)

   第一个作用:使用这个注解之后,该类中的每一个方法都会默认添加@ResponseBody注解

第二个作用:他是一个控制器,有和@Controller注解同样的作用

 

解释:@RestController注解是SpringMVC中提供的一个符合注解,表示在控制器的类上,就相当于给类添加了@Controller注解,同时,在这个类中的每一个方法上都添加了@ResponseBody注解。

 

 

SpringMVC中的拦截器(interceptor):

  拦截器是对控制器中的方法进行拦截,分为preHandlepostHandleafterCompletion

     PreHandle拦截器是对控制器方法执行之前进行作用(有拦截作用,返回false为拦截,返回true表示放行)

     PostHandle拦截器是对控制器方法执行之后进行作用

     AfterCompletion拦截器是对视图渲染结束之后进行作用

 

 

如何创建一个拦截器:

1、编写一个类实现接口HandleInterceptor,重写相应的方法

2、SpringMVC的配置文件中进行配置拦截器

 

配置拦截器的三种方式:

 第一种方式:直接在拦截器中进行添加一个拦截器(注意:使用这种方法由于我们没有设置拦截路径,因此所有的请求都会被拦截)

 

 

 

 

 第二种方式:将编写的拦截器类交给Spring进行管理,本质上和上面一种没有区别(同样,由于没有设置拦截路径,所有的请求都会被拦截)

 

 

 

 

 第三种方式:通过<mvc:interceptor>进行配置拦截器,使用这种方式可以设置拦截路径以及不拦截的路径等

 

 

在设置拦截路径的时候,如果使用的是   /* 表示的是任意一层目录下的文件(如 /a  ,/b下的文件),如果需要设置为任意层,则使用  /**

 

 

第一种方式和第二种方式都是直接设置的拦截器,没有设置拦截路径,所以他会将DispatcherServlet进行处理的所有请求进行拦截(通过DispatcherSevlet进行处理的请求就会被控制器进行处理),第三种方式可以设置拦截路径和不进行拦截的路径。

 

 

多个拦截器的执行顺序:

  如果每一个拦截器的PreHandle都是返回true

  此时多个拦截器的执行顺序和拦截器在SpringMVC的配置文件中的编写顺序有关,Prehandle的执行顺序和在配置文件中的编写顺序相同,但是PosthandleafterComplation的执行顺序和在配置文件中的编写顺序相反

  

  如果有一个拦截器的PreHandle返回了false

  当前返回false和之前的PreHandle会执行(包含返回false的拦截器),PostHandle都不会执行,返回false之前的afterComplation会执行(不包括返回false的拦截器)。

 

 

 

 

异常处理器:

 第一种方式:基于配置的异常处理

实例代码如下:

 

 

 

 

 

 

 第二种方式:通过注解的方式处理异常

实例代码如下:

 

 

通过注解的方式配置SpringMVC

 使用配置类和注解代替web.xml文件和SpringMVC的核心配置文件的功能

 

实例代码:

 

   替换web.xml文件的类:

 

 

 

 

 

替换SpringMVC的配置文件的类:

 

 

 

 

 

 

 

 

 

 

 

设置视图解析器的时候可以借鉴在SpringMVC通过xml文件进行创建的方式进行创建。

 

替换Spring文件的类:

 

 

SpringMVC的常用组件:

1、DispatcherServlet:前端控制器,不需要工程师开发,有框架进行提供

           作用:统一处理请求和响应,整个流程的控制中心,由他调用其他的组件进行处理用户的请求。

    

2、HandlerMapping:处理器映射器,不需要工程师开发,有框架提供

        作用:根据请求的urlmethod方式等信息匹配对应的控制器,即控制器方法

 

3、Handler:处理器,需要工程师开发

        作用:在DispatcherServlert的控制下Handler对具体的用户请求进行处理

 

4、HandlerAdapter:处理器适配器,不需要工程师进行开发,有框架提供

        作用:同构HandlerAdapter对处理器(控制器中的方法)进行执行

 

5、ViewResolver:视图解析器,不需要工程师开发,有框架进行提供

        作用:进行视图解析,得到相应的视图,例如:ThymeleafViewInternalResourceViewRedirectView

 

6、View:视图

        作用:将模型数据通过页面展示给用户

 

posted @ 2022-11-25 20:04  just1t  阅读(27)  评论(0编辑  收藏  举报