spring-mvc

SpringMVC

1,SpringMVC简介

1.1什么是MVC

MVC是一种架构的思想,将软件按照模型、视图、控制器来划分

M:Model,模型层,指工程中的JavaBean,作用是处理数据

javaBean分为两类:

  • 一类称为实体类Bean:专门存储业务数据的,如Student、User等
  • 一类称为业务处理Bean:指Service或Dao对象,专门用于处理业务逻辑和数据访问

V:View,视图层,指工程中的html和jsp等页面,作用是与用户进行交互,展示数据

C:Controller,控制层,指工程中的servlet,作用是接收请求和响应浏览器

MVC的工作流程:用户通过视图层发送请求到服务器,在服务器中请求被Controller接收,Controller调用相应的Model层处理请求,处理完毕将结果返回Controller,Controller再根据请求的结果找到相应的view视图,渲染数据后最终响应给浏览器

1.2什么是springmvc

springmvc是spring的一个后续产品,是spring的一个子项目

springmvc是spring为表述层开发提供的一整套完备的解决方案,在表述层框架经Strust、WebWork、Strust2等诸多产品的历代更迭之后,目前业界普通选择了SpringMVC作为JavaEE项目表述层开发的首选方案

注:三层架构分为表述层(或表示层)、义务逻辑层、数据访问层,表述层表示前台页面和后台servlet

1.3springmvc的特点

  • spring家族的原生产品,与IOC容器等基础设施无缝连接
  • 基于原生的servlet,通过了功能强大的前端控制器DispatcherServlet,对请求和响应进行统一处理
  • 表述层各细分领域需要解决的问题全方位覆盖,提供全面解决方案
  • 代码清新简洁,大幅度提高开发效率
  • 内部组件化程度高,可插拔式组件即插即用,想要什么功能配置相应组件即可
  • 性能卓著,尤其适合现代大型、超大型互联网项目要求

2,入门案例

2.1开发环境

idea2019-2022都行 不过最好不要用最新的 怕不稳定

maven 3.5-3.6都行

tomcat8以上 tomcat8.5

spring版本5.3.1

2.2创建maven工程

  • 添加web模块
  • 打包方式war
  • 引入依赖
springmvc:spring-webmvc  日志:logback-classic servlet:java.servlet-api 整合spring5与thymeleaf:thymeleaf-spring5

2.3配置web.xml

<!--配置springmvc的前端控制器DispatcherServlet-->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

之所以没有写/*是因为那样会将所有的jsp请求做处理,所以我们使用/

jsp在tomcat中有一个对应的jspServlet来处理以.jsp结尾的请求

url-pattern中/和/*的区别:

/:匹配浏览器向服务器发送的所有请求(不包括,jsp)

/*:匹配浏览器向服务器发生的所有请求(包括.jsp)

2.4创建请求控制器

由于前端控制器对浏览器发送的请求进行了统一的处理,但是具体的请求有不同的处理过程,因此需要创建处理具体请求的类,即请求控制器

请求控制器中每一个处理请求的方法成为控制器方法

因为springmvc的控制器由一个POJO(普通的Java类)担任,因此需要通过@Controller注解将其标识为一个控制层组件,交给spring的IOC容器管理,此时springmvc才能够识别控制器的存在

@Controller
public class HelloController{
}

2.5创建springmvc的配置文件

<!--扫描控制层-->
    <context:component-scan base-package="xxx.controller"></context:component-scan>
<!--配置thyleaf视图解析器-->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="org.thymeleaf.spring5.SpringTemplateEngine">
    <property name="templateResolver">
        <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
            <!--视图前缀-->
            <property name="prefix" value="/WEB-INF/templates/"/>
            <!--视图后缀-->
            <property name="templateMode" value="HTML5"/>
            <property name="characterEncoding" value="UTF-8"/>
        </bean>
    </property>
    </bean>
    </property>
</bean>

配置springmvc的前端控制器DispatcherServlet

springMVC的配置文件默认的位置和名称:

位置:web-info下

名称:-servlet.xml ,当前配置下的配置文件名为springMVC-servlet.xml

2.6测试helloworld

  • 实现对首页的访问

在请求控制器中创建处理请求的方法

//@RequestMapping注解:处理请求和控制器方法之间的映射关系
//@RequestMapping注解的value属性可以通过请求地址匹配请求,/表示的当前工程的上下文路径
//localhost:8080/springMVC/
@RequestMapping("/")
public String index(){
    //设置视图名称 (将逻辑视图返回)
    return "index";
}
  • 通过超链接跳转到指定页面

在主页index.html中设置超链接

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
   <meta charset="UTF-8">
    <title>首页</title>
    </head>
<body>
    <h1>首页</h1>
    <a th:href="@{/hello}">HelloWorld</a><br/>
    </body>
</html>

2.7总结

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

希望把配置文件放在resources下,而不是web-inf中templates下

在web.xml中修改

在servlet中 classpath一定要加上不然还是在web-inf下  也要保证类路径下有springmvc.xml
设置springmvc配置文件的位置和名称
<init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:springmvc.xml</param-value>
</init-param>

<!--将DispatcherServlet的初始化时间提前到服务器启动时-->
<load-on-startup>1</load-on-startup>

3,@RequsetMapping注解

3.1@RequestMapping注解的功能

从注解名称上我们可以看到,@RequestMapping注解的作用就是将请求和处理请求的控制器方法关联起来,建立映射关系。

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

3.2@RequestMapping注解的位置

@RequestMapping标识一个类:设置映射请求的请求路径的初始化信息

@RequestMapping标识一个方法:设置映射请求请求路径的具体信息

@Controller
@RequestMapping("/test")
public class RequestMappingController{
    //此时请求映射所映射的请求的请求路径为:/test/testRequestMapping
    @RequestMapping("/testRequestMapping")
    public String testRequestMapping(){
        return "success";
    }
}

3.3@RequestMapping注解的value属性

@RequestMapping注解的value属性通过请求的请求地址匹配请求映射

@RequestMapping注解的value属性是一个字符串类型的数组,表示该请求映射能够匹配多个请求地址所对应的请求

@RequestMapping注解的value属性必须设置,至少通过请求地址匹配请求映射

<a th:href="@{/testRequestMapping}">测试@RequestMapping的value属性-->/testRequestMapping</a><br>
<a th:href="@{/test}">测试@RequestMapping的value属性-->/test</a><br>

servlet可以处理多个请求多设置几个url-pattern

@RequestMapping注解value属性

作用:通过请求的请求路径匹配请求

value属性是数组类型,即当前浏览器所发送请求的请求路径匹配value属性中的任何一个值,则当前请求就会被注解所标识的方法进行处理

3.4@RequestMapping注解的method属性

作用:通过请求的请求方式匹配请求

RequestMethod[] method() default{} 提供了get,post,head,options,put,patch,delete,trace

method属性是RequestMethod类型的数组,即当前浏览器所发送的请求的请求方式匹配method属性中的任何一种请求。则当前请求就会被注解所标识的方法进行处理

若浏览器所发送的请求的请求路径和@RequestMapping注解value属性匹配,但是请求方式不匹配

此时页面报错:405 - Request method ‘xxx’ not supported

@RequestMapping(method=RequestMethod.GET)

@GetMapping,@PostMapping,@DeleteMapping,@PutMapping

3.5@RequestMapping注解得params属性

作用:通过请求的请求参数匹配请求,即浏览器发送的请求的请求参数必须满足params属性的设置

params可以使用四种表达式

param:表示当前所匹配请求的请求参数中必须携带param参数

!param :表示当前所匹配请求的参数中一定不能携带param参数

param=value :表示当前所匹配请求的请求参数中必须携带param参数且值必须为value

param!=value:表示当前所匹配请求的请求参数中必须携带param参数且值一定不能是value

若浏览器所发送请求的请求路径和@RequestMapping注解value属性匹配,但是请求参数不匹配

此时页面报错:400 - Paramter conditions “username” not met for actual request parameters;

3.6@RequestMapping注解的headers属性

作用:通过请求的请求头信息匹配请求,即浏览器发送的请求头信息必须满足headers属性的设置

@RequestMapping注解的headers属性通过请求的请求头信息匹配请求映射

@RequestMapping注解的headers属性是一个字符串类型的数组,可以通过四种表达式设置请求头信息和请求映射的匹配关系

“header”:要求请求映射所匹配的请求必须携带header请求头部信息

“!header”:要求请求映射所匹配的请求必须不能携带header请求头信息

“header=value”:要求请求映射所匹配的请求必须携带header请求头信息且header=value

“header!=value”:要求请求映射所匹配的请求必须携带header请求头信息且header!=value

若当前请求满足@RequestMapping注解的value和method属性,但是不满足headers属性,此时页面显示404错误,即资源未找到

3.7springmvc支持ant风格的路径

在@RequestMapping注解的value属性中设置一些特殊字符

?:表示任意的单个字符

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

**:表示任意层数的任意目录

注意:使用**时,只能使用 / **** /xxx的方式

3.8springmvc支持路径中的占位符

@RequestMapping注解使用路径中的占位符

传统:/deleteUser?id=1

rest:/user/delete/1

需要在@RequestMapping注解的value属性中所设置的路径中,使用{xxx}的方式表示路径中的数据

再通过@PathVariable注解,将占位符所标识的值和控制器方法的形参进行绑定

4springmvc获取请求参数

4.1通过ServletAPI获取

将HttpServletRequest作为控制器方法的形参,此时HttpServletRequest类型的参数表示封装了当前请求的请求报文的对象

@RequestMapping("/testParam")
public String testParam(HttpServletRequest request){
    String username=request.getParameter("username");
    String password=request.getParameter("password");
    System.out.println("username:"+username+",password:"+password);
    return "success";
}

1,只需要在控制器方法得形参位置设置HttpServletRequest类型的形参就可以在控制器方法中使用request对象获取请求参数获取请求参数

2,通过控制器方法的形参获取

只需要在控制器方法的形参位置,设置一个形参,形参的名字和请求参数的名字一致即可

3,@RequestParam:将请求参数和控制器方法的形参绑定

@RequestParam注解的三个属性:value,required,defaultValue

value:设置和形参绑定的请求参数的名字

required:设置是否必须传输value所对应的请求参数

默认为true,表示value所对应的请求参数必须传输,否则页面报错:

400 - Required String parameter ‘xxx’ is not present

若设置为false,则表示value所对应的请求参数不是必须传输,若未传输,则形参值为null

defaultValue:设置当没有传输value所对应的请求参数时,当形参设置的默认值,此时和required属性值无关

4,@RequestHeader:将请求头信息和控制器方法的形参绑定

5,@CookieValue:将cookie数据和控制器方法的形参绑定

6,需要在控制器方法的形参位置设置实体类类型的形参,要保证实体类中的属性的属性名和请求参数的名字保持一致,可以通过实体类类型的形参获取请求参数

7,解决获取请求参数乱码问题,在web.xml中注册CharacterEncodingFilter

注:springmvc中处理编码的过滤器一定要配置到其他过滤器之前,否则无效

ModelAndView包含了model和view的功能

Model:向请求域中共享数据

view:设置逻辑视图实现页面跳转

向域对象共享数据:

1、通过ModelAndView向请求域共享数据

使用ModelAndView时,可以使用其Model功能向请求域共享数据

使用View功能设置逻辑视图,但是控制器方法一定要将ModelAndView作为方法的返回值

2、使用model向请求域共享数据

3,使用modelMap向请求域共享数据

4,使用map向请求域共享数据

5,model和modelmap和map的关系

其实在底层中,这些类型的形参最终都是通过BindingAwareModelMap创建

public class BindingAwareModelMap extends ExtendedModelMap{}

public class ExtendedModelMap extends ModelMap implements Model{}

public class ModelMap extends LinkedHashMap<String,Object>{}

ThymeleafView

在控制器方法中所设置的视图名称没有任何前缀时,此时的视图名称会被springmvc配置文件中所配置的视图解析器解析,视图名称拼接视图前缀和视图后缀所得到的最终路径,会通过转发的方式实现跳转

springmvc中默认的转发视图是InternalResourceView

springmvc中创建转发视图的情况:

当控制器方法中所设置的视图名称以“forword”:为前缀时,创建InternalResourceView视图,此时的视图名称不会被springmvc配置文件中所配置的视图解析器解析,而是会将前缀“forword:”去掉,剩余部分作为最终路径通过转发的方式实现跳转

列入“forword:/”,“forword:/employee”

重定向视图

springmvc中默认的重定向视图是RedirectView

当控制器方法中所设置的视图名称以“redirect:”为前缀时,创建RedirectView视图,此时的视图名称不会被springmvc配置文件中所配置的视图解析器解析,而是会将前缀“redirect:”去掉,剩余部分作为最终路径通过重定向的方式实现跳转

视图控制器view-controller

在控制器方法中,仅仅用来实现页面跳转,即只需要设置视图名称时,可以将处理方法使用view-controller标签进行表示

<!--视图解析器:为当前的请求直接设置视图名称实现页面跳转
若设置视图解析器,则只有视图解析器所设置的请求会被处理,其他的请求将全部404
此时必须在配置一个标签:<mvc:annotation-driven/>
-->
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>

要是添加了上面的标签,除了标签中设置的路径可以访问其他的都不可以

要想其他路径也可以被访问需要开启

<!--开启mvc的注解驱动-->  
<mvc:annotation-driven/>

好多功能都需要以上标签,比如处理静态资源ajax请求处理json

注:浏览器目前只能发送get和post请求

若要发送put和delete请求,需要在web.xml中配置一个过滤器HiddenHttpMethodFilter

配置了过滤器之后,发送的请求要满足两个条件,才能将请求方式转换为put或delete

1,当前请求必须是post

2,当前请求必须传输请求参数_method,_method的值才是最终的请求方式

发送put请求

<!--设置处理请求方式得过滤器-->
<filter>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

要保证原本请求为post

<form th:action="@{/user}" method="post">
    <input type="hidden" name="_method" value="put">
    <input type="submit" value="修改用户信息">
</form>
<!--配置默认的servlet处理静态资源
当前工程的web.xml配置的前端控制器DispatcherServlet是url-pattern是/
tomcat是web.xml配置的DefaultServlet的url-Pattern也是/
此时,浏览器发送的请求会优先被DispatcherServlet进行处理,但是DispatcherServlet无法处理静态资源
若配置了<mvc:default-servlet-handler/>,此时浏览器发送的所有请求都会被DefaultServlet处理
若配置了<mvc:default-servlet-handler/>和<mvc:annotation-driven/>
浏览器发送的请求就先被DispatcherServlet处理,无法处理在交给DefaultServlet处理
-->
<mvc:default-servlet-handler/>

<!--开启mvc的注解驱动-->
<mvc:annotation-driven/>

springmvc该如何处理这些数据

axios({
url:"",//请求路径
method:"",//请求方式
//以name=value&name=value的方式发送的请求参数,
//不管使用的请求方式是get或post,请求参数都会被拼接到请求地址后
//此种方式的请求参数可以通过request.getParameter()获取
params:{},
//以json格式发送请求参数
//请求参数会被保存到请求报文的请求体传输到服务器
//此种方式的请求参数不可以通过request.getParameter()获取
data:{}
}).then(response=>{
console.log(response.data);
});
1,@RequestBody:将请求体中的内容和控制器方法的形参进行绑定
2,使用@RequestBody注解将json格式的请求参数转换为Java对象
a> 导入jackson的依赖
b>在springmvc的配置文件中设置<mvc:annotation-driven/>
c>在处理请求的控制器方法的形参位置,直接设置json格式的请求参数要转换的Java类型的形参,使用@RequestBody注解标识即可

@ResponseBody
@ResponseBody用于标识一个控制器方法,可以将该方法的返回值直接作为响应报文响应到浏览器
使用@ResponseBody注解响应浏览器json格式的数据
a> 导入jackson的依赖
b>在springmvc的配置文件中设置<mvc:annotation-driven/>
c>将需要转换为json字符串的Java对象直接作为控制器方法的返回值,使用@ResponseBody注解标识控制器方法就可以将Java对象直接转换为json字符串,并响应到浏览器

常用的Java对象转换为json的结果:
实体类--》json对象
map--》json对象
list--》json数组

@RestController注解是springmvc提供的一个复合注解,标识在控制器的类上,就相当于为类添加了@Controller注解,并且为其中的每个方法添加了@ResponseBody注解

//创建输入流
InputStream is = new FileInputStream(路径)
//创建字节数组 is.available()获取输入流所对应文件的字节数
byte[] bytes = new byte[is.available()];
//将流读到字节数组中
is.read(bytes);
//创建HttpHeaders对象设置响应头信息
MultiValueMap<String,String> headers = new HttpHeaders();
//设置要下载方式以及下载文件的名字
headers.add("Content-Disposition","attachment;filename=1.jpg");
//设置响应状态码
HttpStatus statusCode = HttpStatus.OK;
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes,headers,statusCode);

文件上传的要求:

1,form表单的请求方式必须为post

2,form表单必须设置属性enctype=“multipart/form-data”

解决文件重名问题加一个uuid随机值替换一下

拦截器的三个方法:

preHandle():再控制器方法执行之前执行,其返回值表示对控制器方法的拦截(false)或放行(true)

postHandle():在控制器方法执行之后执行

afterCompletion:在控制器方法执行之后,且渲染视图完毕之后执行

多个拦截器的执行顺序和springmvc的配置配置文件中配置的顺序有关

preHandle()按照配置的之心顺序,而postHandle()和afterCompletion()按照配置的反序执行

若拦截器中有某个拦截器的preHandle()返回了false

拦截器的preHandle()返回false和它之前的拦截器的preHandle()都会执行

所有的拦截器的postHandle()都不执行

拦截器的preHandle()返回false之前的拦截器的afterCompletion()会执行

@ControllerAdvice 将当前类标识为异常处理的组件

@ExceptionHandler(throwable及其子类的异常)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值