认识springmvc框架
MVC框架
MVC是一种设计思想,将一个应用分成3个基本部分,分别代表着Web应用程序中的3种职责
Model(模型):用于存储数据和完成业务逻辑处理(数据模型)
View(视图):用于显示数据和向控制器提交数据请求
Controller(控制器):根据视图请求调用Model完成业务处理,将处理后的结果交由View进行展示
基于Servlet的MVC模式实现 Model(模型):一个或多个JavaBean对象(数据访问对象和业务逻辑对象)
View(视图):一个或多个JSP页面,用于展示数据和提交表单请求
Controller(控制器):一个或多个Servlet对象,接收视图请求并交由Model处理,将处理结果输出给View显示
Springmvc框架
SpringMVC是Spring框架提供的构建Web应用程序的全功能MVC模块。
搭建Springmvc框架
基于XML的springmvc项目搭建
1.新建一个项目,结构如下(例如)
2.在WEB-INF目录下生成一个web.xml文件
3.在pom.xml中加入springmvc相关依赖坐标
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.8</version>
</dependency>
</dependencies>
4.web.xml中配置SpringMVC核心控制器DispathcerServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>springmvc_demo</display-name>
<!-- 配置DispatcherServlet -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!-- 加载类路径下的spring-mvc.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml,classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 配置DispatcherServlet接受所有URL请求 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 编码过滤器,解决中文乱码问题 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
</web-app>
5.在resources文件夹下创建SpringMVC核心文件springmvc.xml,并添加注解扫描
6.在“WEB-INF”文件夹下,新建views文件夹,用来统一管理所有的jsp页面 在views文件夹下新建“hello.jsp”页面 注意:WEB-INF下的页面 是不能通过浏览器的 url直接访问的,保证系统安全性
7.在“src”下新建包“controller”,包下新建控制器类“HelloController”
说明:
1、@Controller注解标识该类为控制器
2、@RequestMapping("/hello")注解表示用户请求访问hello方法的映射路径url
3、控制器中的方法我们称为Action
8.修改“spring-mvc.xml”配置文件,通过扫描将controller配置到Spring容器中
<!-- 开启SpringMVC框架的注解驱动 -->
<mvc:annotation-driven/>
9.将该项目添加至tomcat运行,在浏览器中输入url进行验证,如下:
http://localhost:8086/heros/hello
基于注解的springmvc项目搭建
1.添加servlet依赖,并新建config包
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
2.在config包下创建配置类SpringMvcConfig替换spring-mvc.xml
3.在config包下创建配置类ServletContainersInitConfig替换web.xml
4.重新启动并测试,结果如下
SpringMVC工作原理
- SpringMVC工作原理 客户端发送请求至前端控制器DispatcherServlet。
- DispatcherServlet收到请求调用HandlerMapping处理器映射器根据请求的URL找到对应的处理器(Controller)。
- Controller调用业务逻辑后,将ModelAndView对象(封装视图和模型信息)返回给DispatcherServlet
- DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
- ViewReslover视图解析器解析后返回具体的View给DispatcherServlet
- DispatcherServlet根据View和Model渲染视图响应给客户端
实现SpringMVC多种类型数据响应
1.返回字符串
直接返回字符串:此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转
资源地址:/WEB-INF/views/hello.jsp
返回带有前缀的字符串:
转发:forward:/WEB-INF/views/hello.jsp
重定向:redirect:/index.jsp
2.返回ModelAndView对象
- 修改hello.jsp页面
- 编写控制器中处理请求的方法
3.回写数据
1.直接返回字符串
-
通过SpringMVC框架注入的response对象,使用response.getWriter().print(“hello world”)回写数据,此时不需要视图跳转,业务方法返回值为void。
- 将需要回写的字符串直接返回,但此时需要通过@ResponseBody注解告知SpringMVC框架,方法返回的字符串不是跳转,而是直接在http响应体中返回。
2.返回对象或集合
-
导入json相关依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
-
开启mvc的注解驱动
-
xml方式:spring核心配置文件中加以下配置
<mvc:annotation-driven/>
-
注解方式:spring配置类上加以下注解
@EnableWebMvc
-
- 创建一个实体类(生成getter和setter方法)
- 编写控制器中处理请求的方法
- 结果如下
4.@ModelAttribute注解
该注解主要的作用是将数据添加到模型对象(Model)中,用于视图页面显示。
有两种使用方式:
- 标注在方法的形参上 可以自动将请求参数绑定到数据模型中
- 标注在方法上 在调用该控制器所有Action之前,会先逐个调用在方法级上标注了@ModelAttribute 的方法,同时会将该方法的返回值自动绑定到数据模型中
5.@SessionAttributes注解
如果需要跨请求、跨页面共享数据,就需要将数据存储到session域中,即存储到HttpSession对象中
两种方式:
- 使用“HttpSession”对象(使用session.removeAttribute("");清除session)
- 使用“@SessionAttributes”注解(该方法可以使得数据模型(Model)中的数据存储一份到session域中 该注解只能在类上使用,不能在方法上使用 使用session.setComplete();方法清除session)
SpringMVC获取不同类型参数
-
客户端请求参数的格式是:name=value&name=value.....
-
服务器端要获得请求的参数,有时还需要进行数据的封装,SpringMVC可以接收如下类型的参数:
-
基本类型参数
-
POJO类型参数
-
数组类型参数
-
集合类型参数
-
-
当请求的参数名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解显示的绑定。
-
获得Restful风格的参数
Restful是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。主要用于客户端和服务器交互类的软件,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存机制等。
Restful风格的请求是使用“url+请求方式”表示一次请求目的的,HTTP协议里面四个表示操作方式的动词如下:
-
GET:用于获取资源
-
POST:用于新建资源
-
PUT:用于更新资源
-
DELETE:用于删除资源
-
-
在业务方法中我们可以使用@PathVariable注解进行请求路径中参数获取工作。
-
自定义类型转换器
SpringMVC默认已经提供了一些常用的类型转换器,例如客户端提交的字符串转换成int型进行参数设置。
但是不是所有的数据类型都提供了转换器,没有提供的就需要自定义转换器,例如:日期类型的数据就需要自定义转换器。
-
@DateTimeFormat 用于声明一个对象属性或者方法参数会被格式化为日期或时间。和@RequestParam注解结合使用时,Spring 会调用 FormattingConversionService.convert(Object, TypeDescriptor, TypeDescriptor) 将日期时间字符串转换成日期时间类型。
-
使用@RequestHeader可以获得请求头信息,相当于web阶段学习的request.getHeader(name)
-
使用@CookieValue可以获得指定Cookie的值
- 文件上传客户端三要素
-
表单项type="file"
-
表单的提交方式是post
-
表单的enctype属性是多部分表单形式,及enctype= “multipart/form-data"
11. 文件上传原理
-
当form表单修改为多部分表单时,request.getParameter()将失效。
-
enctype= “application/x-www-form-urlencoded”时,form表单的正文内容格式是:key=value&key=value&key=value
-
当form表单的enctype取值为Mutilpart/form-data时,请求正文内容就变成多部分形式
获取基本类型参数
1.Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配。
http://localhost:8086/phone/param1?phoneId=1&modelNumber=red mi
2.当请求的参数名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解显示的绑定。
http://localhost:8086/phone/param2?phoneId=1&mNumber=red mi
3.注解@RequestParam还有如下参数可以使用:
-
value::请求参数名称
-
required::指定的请求参数是否必须包括,默认是true,提交时如果没有此参数则报错
-
defaultValue:当没有指定请求参数时,则使用指定的默认值赋值
http://localhost:8086/phone/param3?phoneId=1
获取POJO类型参数
Controller中的业务方法的POJO参数的属性名与请求参数的name一致,参数值会自动映射匹配。
http://localhost:8086/phone/param4?phoneId=1&modelNumber=red mi
获取数组类型参数
http://localhost:8086/phone/param6?nets=4G&nets=5G
解决中文乱码
xml(web.xml)
注解(ServletContainersInitConfig配置类中加入)
获得Restful风格的参数
Restful是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。主要用于客户端和服务器交互类的软件,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存机制等。
Restful风格的请求是使用“url+请求方式”表示一次请求目的,HTTP协议里面四个表示操作方式的动词如下:
-
GET:用于获取资源
-
POST:用于新建资源
-
PUT:用于更新资源
-
DELETE:用于删除资源
http://localhost:8086/phone/param9/7
自定义类型转换器
定义转换器类实现Converter接口
在springmvc配置类中配置自定义类型转换器
Spring MVC 接收 LocalDate、LocalTime 和 LocalDateTime Java 8 时间类型参数
获取请求头
1.@RequestHeader
2.@CookieValue
实现文件上传
1.导入fileupload和io坐标
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
2.配置文件上传解析器
3.编写文件上传代码
拦截器
作用:
Spring MVC的拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(Interceptor Chain)。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP思想的具体实现。
定义拦截器可以通过两种方式
通过实现HandlerInterceptor接口
通过实现WebRequestInterceptor接口
HandlerInterceptor接口里面有三个方法
- preHandle方法:该方法在控制器的处理请求方法前执行,其返回值表示是否中断后续操作,返回true表示继续向下执行,返回false表示中断后续操作,可以进行编码、安全控制、权限校验等处理。
- postHandle方法:该方法在控制器的处理请求方法调用之后,解析视图之前执行,可以通过此方法对模型和视图做进一步的修改。
- afterCompletion方法:该方法在控制器的处理请求方法执行完成后执行,即视图渲染结束后执行,可以通过此方法实现一些资源清理、记录日志等工作。
让自定义的拦截器生效还需要在SpringMVC的配置文件中进行配置
xml
注解
测试拦截器
(1)使用Lombok创建实体类
-
导入Lombok依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
(2)创建控制器
结果
日志框架简介
日志的作用是用来追踪和记录我们的程序运行中的信息,我们可以利用日志很快定位问题,追踪分析。
如果没有日志,程序一旦出现问题,很难快速定位问题。尤其是访问第三方接口、随机或偶尔出现的问题、很难再现的问题 常用的日志框架有很多,比如Log4j,Log4j2,LogBack等
Java日志历史: https://segmentfault.com/a/1190000021121882
- Logback是完全实现SLF4J接口API(也叫日志门面)的日志框架。
- Logback 的架构非常通用,可以应用于不同的环境。目前logback分为三个模块,logback-core、logback-classic和logback-access。
- logback-core 模块为其他两个模块奠定了基础。logback-classic模块原生实现了SLF4J API,因此您可以轻松地在 logback 和其他日志记录框架(例如 log4j 1.x 或 java.util.logging (JUL))之间来回切换。
- logback-access 模块与 Tomcat 和 Jetty 等 Servlet 容器集成,以提供 HTTP 访问日志功能。
Logback日志框架使用
1.引入日志依赖
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.5</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.4.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.4</version>
</dependency>
- logback 基于三个主要组件: Logger、Appender 和 Layout。这三种类的组件协同工作,使开发人员能够通过日志类型和级别来记录日志,并在运行时控制这些日志的格式和报告位置。
- Logger:日志记录器,定义日志内容和日志级别
- Appender :附加器,定义日志输出位置,比如控制台,外部文件,数据库等
- Layout:定义日志输出内容的格式
Logger:日志记录器,定义日志内容和日志级别 Logger有三个属性: name属性:记录器的名称 level属性(可选):记录器的级别,允许的级别从低到高,TRACE < DEBUG < INFO < WARN < ERROR additivity属性(可选):是否允许叠加打印日志, true或false
2.日志记录器(Logger)配置:logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 定义附加器 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%date %msg%n</pattern> </encoder> </appender>
<!-- 根记录器 --> <root level="debug"> <appender-ref ref="STDOUT" /> </root>
<!-- controller记录器 --> <logger name="controller" level="info" additivity="false"> <appender-ref ref="STDOUT" /> </logger>
<!-- controller.TestController记录器 --> <logger name="controller.TestController" level="error" additivity="false"> <appender-ref ref="STDOUT" /> </logger>
</configuration>
3.Java代码获取日志记录器(Logger)
注意:日志记录器会记录指定Level及以上级别的日志信息
附加器(Appender): 不同的附加器会将日志输出到不同的地方,比如控制台附加器、文件附加器、网络附加器等等。
常用的附加器
- 控制台附加器: ch.qos.logback.core.ConsoleAppender
- 文件附加器: ch.qos.logback.core.FileAppender
- 滚动文件附加器: ch.qos.logback.core.rolling.RollingFileAppender
4.控制台附加器: ch.qos.logback.core.ConsoleAppender
<!-- 定义控制台附加器 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <pattern>%date %msg%n</pattern> </encoder>
</appender>
5.文件附加器:ch.qos.logback.core.FileAppender
<!-- 文件附加器 -->
<appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>D:/ssm/myLog.log</file>
<encoder> <pattern>%date %level %class %line %msg%n</pattern>
</encoder>
<append>true</append>
</appender>
6.滚动文件附加器: ch.qos.logback.core.rolling.RollingFileAppender
<!-- 滚动文件附加器 -->
<appender name="ROLLINGFILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>D:/ssm/log_current.log</file>
<encoder> <pattern>%date %level %class %line %msg%n</pattern> </encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>D:/ssm/log_%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
7.滚动策略有两种
1. 基于时间的滚动策略 ch.qos.logback.core.rolling.TimeBasedRollingPolicy
2. 基于大小和时间的滚动策略 ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy
<!-- 滚动文件附加器 -->
<appender name="ROLLINGFILE2" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>D:/ssm/current.log</file>
<encoder> <pattern>%date %level %class %line %msg%n</pattern> </encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>D:/ssm/log_%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxHistory>30</maxHistory> <totalSizeCap>5GB</totalSizeCap> <maxFileSize>1KB</maxFileSize>
</rollingPolicy>
</appender>
实现登录操作
1.创建login.jsp
2.创建成功之后的页面
2.创建控制器
3.运行结果
登录页面
输入参数
点击创建
点击退出,清除session