SpringMVC

SpringMVC操作的是程序的三层结构中UI层的后台部分

一、创建SpringMVC程序

1、开发SpringMVC需要的jar包:

spring-aop spring-bean spring-context commons-logging
spring-core spring-web spring-webmvc

2、创建配置文件springmvc.xml

选择常用的命名空间:beans,aop,context,mvc

3、开发流程
普通的servlet流程:

请求-url-pattern-交给对应的servlet去处理

以springmvc代替servlet的流程:

配置一个SpringMVC自带的servlet,

即在中配置org.springframework.web.servlet.DispatcherServlet,并配置
/
代表拦截所有并交给SpringMVC处理。

通过

contextConfigLocation
classpath:springmvc.xml

指定springmvc配置文件的路径。

如果要省略,须把springmvc配置文件放到默认路径:WEB-INF中,并根据
…中的值把
文件名改为…-servlet.xml

通过注解把普通类变为servlet,在类前添加@Controller注解即可

4、补充
@RequestMapping(value="…",method=…,params=…)

value指定映射名称,它还有ant风格的请求路径,如 ?代表单个字符,
*任意个字符(0或多个),**代表任意路径

@RequestMapping(value=“x1/a?c/a”)

在访问…/x1/a?c/a时能用任意单个字符替换?访问同一个页面,如…/x1/asc/a和…/x1/abc/a都可以

@RequestMapping(value="x1//a")

在访问…/x1//a时能用任意字符(不限个数)替代*访问同一个页面,如…/x1/aaa/a和…/x1/aaaaa/a都可以

@RequestMapping(value="x1//a")

在访问…/x1//a时能用任意目录结构代替**访问同一个页面,如…/x1/s/c/q/w/a和…/x1/qwe/a都可以

method指定请求方式

常见的有get,post,delete,put,如RequestMethod.POST

params指定name标签中的值
如params={“xxx=yyy”,“aaa”!=“bbb”,"!ccc"}

此时映射该方法的链接里需要有

不能有

这个可有可无,若有的话,则打开链接后需在xxx的输入框中输入yyy,在aaa的输入框中输入除bbb之外的数据才能成功运行该方法

可以添加在类和方法前面

若只在方法前添加,则映射时只需填括号中的内容,若两者都添加,则在映射该方法时须添加类的命名和/
如在类前@RequestMapping(value=“class”),在方法前
@RequestMapping(value=“method”),映射该方法时需要填写 class/method

@PathVariable

可以用来动态传值(仅限于get提交方式)
在java文件中创建使用该注解方法

@RequestMapping(value = "hello/{name}")	
    public String hello(@PathVariable("name") String name){
        System.out.println(name);
        return "success";
    }

// @RequestMapping(value = “hello/{name}”)中的{name}会接受前端传来的参数,并把参数传给PathVariable(“name”)里的“name”,最后再传给后面的String name中的name

在index.jsp文件中使用该超链接
hello
开启tomcat后到浏览器使用进入项目的页面,点击hello超链接后会程序会把world传给java文件,此时控制台会打印world

二、SpringMVC的Rest编程风格

1、提交方式一般为GET POST DELETE PUT

普通浏览器只支持get和post方式,其他请求方式如 delete/put请求是通过 过滤器新加入的支持

2、实现put/delete请求(请求方式为post)
a、增加过滤器
<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>
b、前端表单
**请求方式为post**

通过隐藏域的value值 设置实际的请求方式

c、控制器
@RequestMapping(value = "TestRest/{id}", 
method = RequestMethod.DELETE)
@ResponseBody()
public String Delete(@PathVariable("id") Integer id) {
    System.out.println("delete:删" + id);
    return "success";
}

通过method = RequestMethod.DELETE,匹配具体的请求方式

此外,当映射名相同时@RequestMapping(value = “TestRest”,可以通过method处理不同的请求

d、过滤器中 处理put|delete请求的部分源码:
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    HttpServletRequest requestToUse = request;
    if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) {
        String paramValue = request.getParameter(this.methodParam);
        if (StringUtils.hasLength(paramValue)) {
            String method = paramValue.toUpperCase(Locale.ENGLISH);
            if (ALLOWED_METHODS.contains(method)) {
                requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);
            }
        }
    }

    filterChain.doFilter((ServletRequest)requestToUse, response);
}

原始请求:request,该请求默认只支持get post header

但是如果是“POST”并且有隐藏域

则过滤器 将原始的请求 request加入新的请求方式DELETE,并将原始请求 转为 requestToUse 请求(request+Delete请求),最后将requestToUse 放入请求链中,后续使用request时,实际就使用改造后的requestToUse

3、RequestParam()

@RequestParam("uname") String name,

@RequestParam(value = "value=uage",required = false,defaultValue = "23") Integer age

@RequestParam(“uname”):接受前台传递的值,等价于request.getParameter(“uname”);

required = false:该属性 不是必须的

defaultValue = “23”:默认值23

4、@RequestHeader:获取请求头信息

public String testRequestHeader(@RequestHeader("Accept-Language") String al)

通过@RequestHeader("Accept-Language") String al 获取请求头中Accept-Language值,并将值保存在al变量中

5、@CookieValue
前置知识

服务端在接受客户端第一次请求时,会给该客户端分配一个session(该session包含一个sessionId),并且服务端会在第一次相应客户端时,将该sessionId赋值给JSESSIONID并传递给客户端

左边客户端,右边服务端

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-um24UiE2-1616404077775)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210222220611128.png)]

2、通过mvc获取服务端传给客户端的cookie的值

public String testCookieValue(@CookieValue("JSESSIONID") String jsessionid)

跟@RequestHeader的流程一样

@CookieValue("JSESSIONID") String jsessionid

6、SpringMVC处理对象

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7、小结:SpringMVC处理各种参数的流程/逻辑

在这里插入图片描述

三、模型数据传递

1、mvc的数据传输模型

用户从view输入31传给Controller,Controller将31传给StudentService.queryStudent()查询31号学生并获得具体数据,之后再将数据传递给view,此时需要保存的数据有V和M

在这里插入图片描述

2、跳转时要带数据:V、M使用的方式
1、把数据放在request作用域里
1、ModelAndView

后端页面:

在这里插入图片描述

前端页面:

在这里插入图片描述

2、ModelMap

前端页面同ModelAndView
后端页面:
在这里插入图片描述

3、Map

前端页面同ModelAndView

后端页面:在这里插入图片描述

4、Model

前端页面同ModelAndView

后端页面:在这里插入图片描述

2、@SessionAttributes

将数据放入session域中

1、指定单个对象:

在这里插入图片描述

2、指定一个类,即该类产生的对象都会放在session域中

在这里插入图片描述

3、@ModelAttribute

在更新时使用

1、原理图

将zs的值修改为ls并且其他数据都保存

在这里插入图片描述

2、实现效果

将上方student的值传给的下方的student中

在这里插入图片描述

3、实现过程

通过@ModelAttribute修饰的方法,会在每次请求前先执行;

并且该方法的参数map.put()可以将 对象 放入 即将查询的参数中

必须满足约定:map.key(k,v)中的k 必须是即将查询的方法参数 的首字母小写

如下图的"student"和Student

在这里插入图片描述

如果不一致,需要通过@ModelAttribu来指定

在这里插入图片描述

四、视图与解析器

1、流程

无论Controller的返回值是哪种,它都会转成ModelAndView对象,并会交给视图解析器(ViewResolver)解析,解析完成后就变成视图,视图经过视图渲染后就能被用户看到。

在这里插入图片描述

2、视图、视图解析器
1、视图的顶级接口:View

在这里插入图片描述

2、视图解析器:ViewResolver

在这里插入图片描述

3、常见的视图和解析器

InternalResoureceView、InternalResourceViewResolver

3、JstlView
1、继承自InternalResoureceView

在这里插入图片描述

springMVC解析jsp时 会默认使用InternalResoureceView,如果发现jsp中包含了jstl语言会自动转为JstlView

2、作用

可以解析jstl / 实现国际化操作

3、国际化

针对不同地区、不同国家,进行不同的显示

4、实现国际化步骤
a、创建资源文件

需满足的条件

在这里插入图片描述

格式为:基名_____语言_____国家.properties 或者 基名_____语言_____.properties

基名一般为base或i18n

如base_zh_CN.properties

属性值寻找规律:

在这里插入图片描述

中文资源文件需要以ASCII码的形式,即如下图

在这里插入图片描述

可通过在命令行运行jdk的bin目录中的native2ascii.exe,如下图

在这里插入图片描述

b、配置springmvc.xml,加载资源文件

在这里插入图片描述

c、流程图

在这里插入图片描述

d、通过jstl使用国际化

需要jar包:

<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
</dependency>
4、常见功能
1、简化处理流程

正常的处理流程:index.jsp -> Controller(@RequestMapping) -> success.jsp

简化后的处理流程:index.jsp -> success.jsp ,即省略掉Controller(@RequestMapping)

可以用SpringMVC实现:

<mvc:view-controller path="请求路径" view-name="返回的视图名称">

如下图:

在这里插入图片描述

当Controller的路径也相同的话,会跳到标签,忽略Controller

在这里插入图片描述

如果想让@RequestMapping(“a”) 和 共存,需要加入一个注解:

<mvc:annotation-driven></mvc:annotation-driven>

5、指定请求方式

指定后不会被视图解析器加上前缀后缀,需要自己把路径写全

使用这种方式后国际化会失败

1、请求转发

返回时用forward指定

格式为:return "forward":具体路径;

2、重定向

返回时用redirect指定

格式为:return "redirect":具体路径;

在这里插入图片描述

6、处理静态资源
1、静态资源

html、css、js、图片、视频等。不能与用户交互。

2、动态资源

可以与用户交互,因为时间/地点的不同 而结果不同的内容(百度:天气)

3、springmvc中的静态资源
1、问题

在springmvc中,如果直接访问静态资源会404

原因如下:

所有请求被通配符”/“拦截,进而交给springmvc的入口DispatcherServlet去处理

DispatcherServlet处理方式:找该请求映射对应的@RequestMapping

在这里插入图片描述

将静态资源放在初始目录下后的链接为:

http://localhost:8080/springMVCProject/img.png

经过DispatcherServlet处理后会变成

@RequestMapping(“img.png”)

这样就找不到静态资源了

2、解决方案

如果是需要springmvc处理的,则交给@RequestMapping()处理;

如果不需要springmvc处理的,则使用tomcat默认的Servlet去处理。

实现方法:

1、将放置静态资源的目录设置为资源目录

2、在springmvc.xml中增加两个配置即可

<mvc:default-servlet-handler></mvc:default-servlet-handler>

( 该注解会在springmvc接收到一个没有对应的@RequestMapping()的请求时,将该请求交给服务器默认的servlet去处理(直接访问))

<mvc:annotation-driven></mvc:annotation-driven>

(默认的Servlet处理过程:如果有 对应的请求拦截,则交给相应的Servlet去处理,如果没有对应的Servlet,则直接访问)

Servlet访问过程如下图:

在这里插入图片描述

tomcat默认的Servlet位置:\conf\web.xml的DefaultServlet

在这里插入图片描述

7、类型转换
1、类型转换图

在这里插入图片描述

2、springmvc自带的常见类型转换器
public String Delete(@PathVariable("id") String id)

既可以接收int类型数据id 也可以接收String类型的id

3、自定义类型转换器
1、编写自定义类型转换器的类

实现Converter接口

在这里插入图片描述

2、将编写的转换器加入到springmvc中

在这里插入图片描述

3、注意问题

后端需要加上@RequestParam()来指定前端传递的内容,否则会跟自带的类型转换器冲突,导致无法判断

在这里插入图片描述

在这里插入图片描述

五、数据格式化

1、实现步骤
1、配置

在这里插入图片描述

2、通过注解使用
1、@DateTimeFormat()

日期格式化注解

在这里插入图片描述

2、@NumberFormat()

数字格式化注解

在这里插入图片描述

3、获取错误信息

在这里插入图片描述

在这里插入图片描述

2、FormattingConversionServiceFactoryBean的功能

既可以实现格式化,又可以实现类型转换

在这里插入图片描述

六、错误消息处理和数据校验

1、错误消息处理

将错误信息放到map中并通过request域传给前端

后端:

此时需要验证的数据是Student中的birthday,SpringMVC要求 如果校验失败 则将错误信息 自动放入该对象之后紧挨着的 BindingResult中。即下图中的Student student,BindingResult result不能有其他参数

在这里插入图片描述

前端:

在这里插入图片描述

2、数据校验
1、JSR 303 提供的标准注解如下表

在这里插入图片描述

2、Hibernate Validator

在这里插入图片描述

1、需要的jar包
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.17.Final</version>
</dependency>
<dependency>
    <groupId>javax.el</groupId>
    <artifactId>javax.el-api</artifactId>
    <version>3.0.0</version>
</dependency>
<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.el</artifactId>
    <version>3.0.0</version>
</dependency>
2、配置

<mvc:annotation-driven></mvc:annotation-driven>

此时该注解的作用:要实现Hibernate Validator/JSR303 校验(或者其他各种校验),必须实现SpringMVC提供的一个接口:ValidatorFactory

但SpringMVC已经实现过了,LocalValidatorFactoryBean是ValidatorFactory的一个实现类。

<mvc:annotation-driven></mvc:annotation-driven>会在springmvc容器中自动加载一个LocalValidatorFactoryBean类,因此可以直接实现数据校验。

3、使用注解

在属性前添加注解

在这里插入图片描述

在校验的Controller中,给校验的对象倩增加@Valid

在这里插入图片描述

七、处理json数据

1、添加注解
1、@ResponseBody

当控制器为@Controller时,默认返回视图,需要在方法前添加注解@ResponseBody,添加后就不会走视图解析器,而是直接返回一个字符串

在这里插入图片描述

2、@RestController

添加后整个控制器就默认返回字符串格式

在这里插入图片描述

2、处理乱码
1、只处理一个

在@RequestMapping中添加produces = "application/json;charset=utf-8"

在这里插入图片描述

2、配置所有

在springmvc.xml文件中添加

<mvc:annotation-driven>
    <mvc:message-converters register-defaults="true">
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <constructor-arg value="UTF-8"></constructor-arg>
        </bean>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                    <property name="failOnEmptyBeans" value="false"></property>
                </bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>
3、Jackson
1、添加依赖
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.1</version>
</dependency>
2、使用
1、传递一个对象

在这里插入图片描述

2、传递一个集合

在这里插入图片描述

3、处理时间对象

时间解析后的默认格式为:Timestamp,也就是时间戳

解决方法:

1、使用SimpleDateFormat转换时间格式

在这里插入图片描述

2、使用ObjectMapper自带的格式转化

在这里插入图片描述

4、fastjson
1、添加依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.75</version>
</dependency>
2、常用类

在这里插入图片描述

3、使用

在这里插入图片描述

4、其他操作

在这里插入图片描述

八、文件上传

1、添加依赖
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.8.0</version>
</dependency>
2、实现接口
1、需要实现MultiparResolver接口

在这里插入图片描述

2、SpringMVC提供该接口的实现类
CommonsMultipartResolver

在这里插入图片描述

3、具体步骤
1、配置CommonsMultipartResolver

将其加入springioc容器

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="UTF-8"></property>
    <!-- 上传单个文件的最大值,单位Bytes;如果-1,表示无限制 -->
    <property name="maxUploadSize" value="102400000"></property>
</bean>

注意:

id值不能变,原因:springIoc容器在初始化时,会自动寻找一个ID="multipartResolver"的bean,如果有,自动将该bean配置到ioc容器里,如果没有,则会忽略该bean
2、处理方法
后端

在这里插入图片描述

前端

在这里插入图片描述

九、拦截器

1、原理

原理跟过滤器相同

要想实现拦截器,必须实现接口HandlerInterceptor

结构图

在这里插入图片描述

流程图:

在这里插入图片描述
在这里插入图片描述

2、添加依赖
需要添加HttpServletRequest 和 HttpServletResponse需引用的依赖包
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>
3、编写接口实现类

在这里插入图片描述

4、配置

将自己写的拦截器 配置到springmvc容器中

1、默认

在这里插入图片描述

2、配置指定拦截器

在这里插入图片描述

5、多个拦截器的过程

在这里插入图片描述

十、异常处理

1、简介
1、异常实现接口

HandlerExceptionResolver

2、接口实现类
1、ExceptionHandlerExceptionResolver

主要提供了@ExceptionHandler注解,并通过该注解处理异常

在这里插入图片描述

2、ResponseStatusExceptionResolver

自定义异常显示页面,通过注解@ResponseStatus实现

在这里插入图片描述

3、DefaultHandlerExceptionResolver

springmvc自带的默认异常处理器,提供了以下的异常处理

在这里插入图片描述

4、SimpleMappingExceptionResolver

通过配置来实现异常处理

2、使用
1、@ExceptionHandler注解

在方法前使用该注解,转为专门异常处理的方法(只能捕获当前类中的异常)

//在注解的"{}"中写入要捕获的异常,控制器就会自动捕获,可以写多个异常
//如果在本类中捕获到相对应的异常,就自动转入该方法,相当于catch
//该方法可以捕获本类中 抛出的ArithmeticException异常
@ExceptionHandler({ArithmeticException.class})
public ModelAndView handlerArithmeticException(ArithmeticException e){
    ModelAndView mv = new ModelAndView("error");
    System.out.println(e);
    mv.addObject("e",e);
    return mv;
}

在这里插入图片描述

2、@ControllerAdvice注解

在类前添加该注解,使整个类转为专门处理异常的类,这样其他类出现异常也就能处理(需要将该类添加进扫描包)之后在要处理异常的方法前加@ExceptionHandler注解即可

在这里插入图片描述

在这里插入图片描述

3、@ResponseStatus

可在类和方法前添加

  • 下面演示类

自定义一个异常类并在其前加上@ResponseStatus注解,在value中写上异常编号,在reason中写上异常描述信息

在这里插入图片描述

通过抛出该异常显示信息

在这里插入图片描述

前端显示信息

在这里插入图片描述

4、通过springmvc配置

在这里插入图片描述

3、异常处理路径

处理先后顺序:

  • 当前类 ——> 其他类 ——> 配置
  • 如果类中有多个能处理该异常的方法,则是子异常优先

如下图中有两个添加处理异常注解的方法,其中ArithmeticException是Exception的子类,如果出现ArithmeticException异常,会被handlerArithmeticException捕获

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值