SpringMVC入门

1. Spring与Web环境集成

1.1 ApplicationContext应用上下文获取方式

应用上下文对象是通过new ClasspathXmlApplicationContext(spring配置文件) 方式获取的,但是每次从 容器中获得Bean时都要编写new ClasspathXmlApplicationContext(spring配置文件) ,这样的弊端是配置 文件加载多次,应用上下文对象创建多次。

在Web项目中,可以使用ServletContextListener监听Web应用的启动,我们可以在Web应用启动时,就加载Spring的配置文件,创建应用上下文对象ApplicationContext,在将其存储到最大的域servletContext域 中,这样就可以在任意位置从域中获得应用上下文ApplicationContext对象

1.2 Spring提供获取应用上下文的工具

上面的分析不用手动实现,Spring提供了一个监听器ContextLoaderListener就是对上述功能的封装,该监 听器内部加载Spring配置文件,创建应用上下文对象,并存储到ServletContext域中,提供了一个客户端工具WebApplicationContextUtils供使用者获得应用上下文对象。

所以我们需要做的只有两件事:

① 在web.xml中配置ContextLoaderListener监听器(导入spring-web坐标)

② 使用WebApplicationContextUtils获得应用上下文对象ApplicationContext

2. SpringMVC的简介

2.1 SpringMVC概述

SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于 SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 中。

SpringMVC 已经成为目前最主流的MVC框架之一,并且随着Spring3.0 的发布,全面超越 Struts2,成为最优 秀的 MVC 框架。它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时 它还支持 RESTful 编程风格的请求。

2.3 SpringMVC快速入门

需求:客户端发起请求,服务器端接收请求,执行逻辑并进行视图跳转。

开发步骤:

  • ① 导入SpringMVC相关坐标

  • ② 配置SpringMVC核心控制器DispathcerServlet

  • ③ 创建Controller类和视图页面

  • ④ 使用注解配置Controller类中业务方法的映射地址

  • ⑤ 配置SpringMVC核心文件 spring-mvc.xml

  • ⑥ 客户端发起请求测试

2.3 SpringMVC流程图示

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

3. SpringMVC的组件解析

3.1 SpringMVC的执行流程

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

  • ① 用户发送请求至前端控制器DispatcherServlet。
  • ② DispatcherServlet收到请求调用HandlerMapping处理器映射器。
  • ③ 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果 有则生成)一并返回给DispatcherServlet。
  • ④ DispatcherServlet调用HandlerAdapter处理器适配器。
  • ⑤ HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
  • ⑥ Controller执行完成返回ModelAndView。
  • ⑦ HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
  • ⑧ DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
  • ⑨ ViewReslover解析后返回具体View。
  • ⑩ DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。DispatcherServlet响应用户。

3.2 SpringMVC注解解析

  1. 前端控制器:DispatcherServlet

    • 用户请求到达前端控制器,它就相当于 MVC 模式中的 C,DispatcherServlet 是整个流程控制的中心,由 它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。
  2. 处理器映射器:HandlerMapping

    • HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的 映射方式,例如:配置文件方式,实现接口方式,注解方式等。
  3. 处理器适配器:HandlerAdapter

    • 通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理 器进行执行。
  4. 处理器:Handler

    • 它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由 Handler 对具体的用户请求进行处理。
  5. 视图解析器:View Resolver

    • View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名,即 具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。
  6. 视图:View

    • SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。最 常用的视图就是 jsp。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程 序员根据业务需求开发具体的页面

@RequestMapping

作用:用于建立请求 URL 和处理请求方法之间的对应关系

位置:

  • 类上,请求URL 的第一级访问目录。此处不写的话,就相当于应用的根目录
  • 方法上,请求 URL 的第二级访问目录,与类上的使用@ReqquestMapping标注的一级目录一起组成访问虚拟路径

属性:

  • value:用于指定请求的URL。它和path属性的作用是一样的
  • method:用于指定请求的方式
  • params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须和配置的一模一样

例如:

  • params = {“accountName”},表示请求参数必须有accountName
  • params = {“moeny!100”},表示请求参数中money不能是100

1.mvc命名空间引入

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

2.组件扫描

SpringMVC基于Spring容器,所以在进行SpringMVC操作时,需要将Controller存储到Spring容器中,如果使 用@Controller注解标注的话,就需要使用进行组件扫描。

<context:component-scan base-package=path/>

3.视图解析器
在这里插入图片描述
在这里插入图片描述

4. SpringMVC的数据响应

4.1 页面跳转

4.1.1 返回字符串形式

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

4.1.2 返回ModelAndView对象

@RequestMapping("/quick2")
public ModelAndView quickMethod2(){
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("redirect:index.jsp");
    return modelAndView;
}
@RequestMapping("/quick3")
public ModelAndView quickMethod3(){
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("forward:/WEB-INF/views/index.jsp");
    return modelAndView;
}

4.1.3 向request域存储数据

@RequestMapping("/quick")
public String quickMethod(HttpServletRequest request){
    request.setAttribute("name","zhangsan");
    return "index";
}@RequestMapping("/quick3")
public ModelAndView quickMethod3(){
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("forward:/WEB-INF/views/index.jsp");
    modelAndView.addObject("name","lisi");
    return modelAndView;
}

4.2 回写数据

4.2.1 直接返回字符串

Web基础阶段,客户端访问服务器端,如果想直接回写字符串作为响应体返回的话,只需要使用 response.getWriter().print(“hello world”) 即可,那么在Controller中想直接回写字符串该怎样呢?

① 通过SpringMVC框架注入的response对象,使用response.getWriter().print(“hello world”) 回写数 据,此时不需要视图跳转,业务方法返回值为void。

@RequestMapping("/quick4")
public void quickMethod4(HttpServletResponse response) throws 
IOException {
	response.getWriter().print("hello world");
}

② 将需要回写的字符串直接返回,但此时需要通过@ResponseBody注解告知SpringMVC框架,方法 返回的字符串不是跳转是直接在http响应体中返回。

@RequestMapping("/quick5")
@ResponseBody
public String quickMethod5() throws IOException {
	return "hello springMVC!!!";
}

③在异步项目中,客户端与服务器端往往要进行json格式字符串交互,此时我们可以手动拼接json字符串返回。

@RequestMapping("/quick6")
@ResponseBody
public String quickMethod6() throws IOException {
	return "{\"name\":\"zhangsan\",\"age\":18}";
}

通过jackson转换json格式字符串,回写字符串。

@RequestMapping("/quick7")
@ResponseBody
public String quickMethod7() throws IOException {
    User user = new User();
    user.setUsername("zhangsan");
    user.setAge(18);
    ObjectMapper objectMapper = new ObjectMapper();
    String s = objectMapper.writeValueAsString(user);
    return s;
}

PS:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.0</version>
</dependency>
<bean class="org.springframework.web.servlet.mvc.method.annotation
.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.json
            .MappingJackson2HttpMessageConverter">
            </bean>
        </list>
    </property>
</bean>

4.2.2 返回对象或集合

@RequestMapping("/quick8")
@ResponseBody
public User quickMethod8() throws IOException {
    User user = new User();
    user.setUsername("zhangsan");
    user.setAge(18);
	return user;
}

在方法上添加@ResponseBody就可以返回json格式的字符串,但是这样配置比较麻烦,配置的代码比较多, 因此,我们可以使用mvc的注解驱动代替上述配置。 在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。 使用==< mvc:annotation-driven />==自动加载 RequestMappingHandlerMapping(处理映射器)和 RequestMappingHandlerAdapter( 处 理 适 配 器 ),可用在Spring-xml.xml配置文件中使用 替代注解处理器和适配器的配置。 同时使用默认底层就会集成jackson进行对象或集合的json格式字符串的转换。

5. SpringMVC获得请求数据

5.1 获得请求参数

客户端请求参数的格式是:name=value&name=value… …

服务器端要获得请求的参数,有时还需要进行数据的封装,SpringMVC可以接收如下类型的参数:

  • 基本类型参数
  • POJO类型参数
  • 数组类型参数
  • 集合类型参数

5.2 获得基本类型参数

Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配。

5.3 获得POJO类型参数

//http://localhost:8080/quick9?username=zhangsan&age=12

public class User {
    private String username;
    private int age;
    getter/setter…
}
@RequestMapping("/quick10")
@ResponseBody
public void quickMethod10(User user) throws IOException {
	System.out.println(user);
}

5.4 获得数组类型参数

//http://localhost:8080/quick11?strs=111&strs=222&strs=333

@RequestMapping("/quick11")
@ResponseBody
public void quickMethod11(String[] strs) throws IOException {
	System.out.println(Arrays.asList(strs));
}

5.5 获取集合类型参数

<form action="${pageContext.request.contextPath}/quick12" method="post">
    <input type="text" name="userList[0].username"><br>
    <input type="text" name="userList[0].age"><br>
    <input type="text" name="userList[1].username"><br>
    <input type="text" name="userList[1].age"><br>
    <input type="submit" value="提交"><br>
</form>

@RequestMapping("/quick12")
@ResponseBody
public void quickMethod12(Vo vo) throws IOException {
	System.out.println(vo.getUserList());
}

当使用ajax提交时,可以指定contentType为json形式,那么在方法参数位置使用@RequestBody可以 直接接收集合数据而无需使用POJO进行包装。

<script>
//模拟数据
    var userList = new Array();
    userList.push({username: "zhangsan",age: "20"});
    userList.push({username: "lisi",age: "20"});
    $.ajax({
        type: "POST",
        url: "/itheima_springmvc1/quick13",
        data: JSON.stringify(userList),
        contentType : 'application/json;charset=utf-8'
    });
</script>

当使用ajax提交时,可以指定contentType为json形式,那么在方法参数位置使用@RequestBody可以 直接接收集合数据而无需使用POJO进行包装。

@RequestMapping("/quick13")
@ResponseBody
public void quickMethod13(@RequestBody List<User> userList) throws 
IOException {
	System.out.println(userList);
}

注意:通过谷歌开发者工具抓包发现,没有加载到jquery文件,原因是SpringMVC的前端控制器 DispatcherServlet的url-pattern配置的是/,代表对所有的资源都进行过滤操作,我们可以通过以下两种 方式指定放行静态资源:

• 在spring-mvc.xml配置文件中指定放行的资源

​ <mvc:resources mapping="/js/**" location="/js/"/>

• 使用标签

5.6 请求数据乱码问题(filter)

<filter>
    <filter-name>CharacterEncodingFilter</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>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

5.7 参数绑定注解@requestParam

<form action="${pageContext.request.contextPath}/quick14" method="post">
    <input type="text" name="name"><br>
    <input type="submit" value="提交"><br>
</form>

@RequestMapping("/quick14")
@ResponseBody
public void quickMethod14(@RequestParam("name") String username) throws 
IOException {
	System.out.println(username);
}

5.8 获得Restful风格的参数

Restful是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。主要用于客户端和服务 器交互类的软件,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存机制等。

Restful风格的请求是使用“url+请求方式”表示一次请求目的的,HTTP 协议里面四个表示操作方式的动词如下:

  • GET:用于获取资源
  • POST:用于新建资源
  • PUT:用于更新资源
  • DELETE:用于删除资源

例如:

  • /user/1 GET : 得到 id = 1 的 user
  • /user/1 DELETE: 删除 id = 1 的 user
  • /user/1 PUT: 更新 id = 1 的 user
  • /user POST: 新增 user
//http://localhost:8080/quick19/zhangsan

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

5.9 自定义类型转换器

自定义类型转换器的开发步骤:

① 定义转换器类实现Converter接口

public class DateConverter implements Converter<String,Date>{
    @Override
    public Date convert(String source) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        try {
        	Date date = format.parse(source);
        	return date;
        } catch (ParseException e) {
        	e.printStackTrace();
        }
        return null;
    }
}

② 在配置文件中声明转换器

<bean id="converterService" 
class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <list>
        	<bean class="**.DateConverter"/>
        </list>
    </property>
</bean>

③ 在中引用转换器

<mvc:annotation-driven conversion-service="converterService"/>

5.10 获取请求头(request)

5.11 文件上传

  1. 文件上传客户端三要素

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

  1. 文件上传原理

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

5.12 单文件上传

① 导入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>

② 配置文件上传解析器

<bean id="multipartResolver" 
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!--上传文件总大小-->
    <property name="maxUploadSize" value="5242800"/>
    <!--上传单个文件的大小-->
    <property name="maxUploadSizePerFile" value="5242800"/>
    <!--上传文件的编码类型-->
    <property name="defaultEncoding" value="UTF-8"/>
</bean>

③ 编写文件上传代码

@RequestMapping("/quick20")
@ResponseBody
public void quickMethod20(String name,MultipartFile uploadFile) throws 
IOException {
    //获得文件名称
    String originalFilename = uploadFile.getOriginalFilename();
    //保存文件
    uploadFile.transferTo(new File("C:\\upload\\"+originalFilename));
}

5.13 多文件上传(文件数组)

6. SpringMVC Interceptor

6.1 Interceptor的作用

Spring MVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理后处理

将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(Interceptor Chain)。在访问被拦截的方 法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP思想的具体实现。

6.2 Interceptor 与 filter的区别

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

6.3 Interceptor 快速入门

① 创建拦截器类实现HandlerInterceptor接口

public class MyHandlerInterceptor1 implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse 
    response, Object handler) {
        System.out.println("preHandle running...");
        return true;
    }
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
    	System.out.println("postHandle running...");
    }
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    	System.out.println("afterCompletion running...");
    }
}

② 配置拦截器

<!--配置拦截器-->
<mvc:interceptors>
    <mvc:interceptor>
    	<mvc:mapping path="/**"/>
    	<bean class="com.itheima.interceptor.MyHandlerInterceptor1"/>
    </mvc:interceptor>
</mvc:interceptors>

③ 测试拦截器的拦截效果

@RequestMapping("/quick23")
@ResponseBody
public ModelAndView quickMethod23() throws IOException, ParseException {
	System.out.println("目标方法执行....");
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject("name","itcast");
    modelAndView.setViewName("index");
    return modelAndView;
}

7. SpringMVC异常处理机制

7.1 异常处理的思路

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

7.2 异常处理两种方式

  • 使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver

  • 实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值