Spring-MVC总结

Spring-MVC总结

1. SpringMVC的概述

Spring MVC框架是一个开源的Java平台,为开发强大的基于JavaWeb应用程序提供全面的基础架构支持,框架提供了MVC(模型 - 视图 - 控制器)架构和用于开发灵活和松散耦合的Web应用程序的组件。

模型(Model) 封装了应用程序数据,通常它们将由POJO类组成。

视图(View) 负责渲染模型数据,一般来说它生成客户端浏览器可以解释HTML输出。

控制器(Controller) 负责处理用户请求并构建适当的模型,并将其传递给视图进行渲染。

2. 核心DispatcherServlet程序(相当于BaseServlet)

服务器交互请求响应流程图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ym82zmEV-1574917565574)(file:///C:\Users\尚硅谷\AppData\Local\Temp\ksohtml15800\wps1.jpg)]

3. 搭建Spring-MVC运行时环境

**3.**1 创建一个动态的web工程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HZ0BO73y-1574917565575)(file:///C:\Users\尚硅谷\AppData\Local\Temp\ksohtml15800\wps2.jpg)]

3.2导入SpringMVC所需jar****包

commons-logging-1.1.3.jar

log4j-1.2.17.jar

spring-aop-4.0.0.RELEASE.jar

spring-beans-4.0.0.RELEASE.jar

spring-context-4.0.0.RELEASE.jar

spring-core-4.0.0.RELEASE.jar

spring-expression-4.0.0.RELEASE.jar

spring-web-4.0.0.RELEASE.jar

spring-webmvc-4.0.0.RELEASE.jar

3.3 配置日志文件log4j

(1) log4j.properties

# Global logging configuration

log4j.rootLogger=INFO, stdout

# Console output…

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

3.4配置SpringMVC的xml****文件

<?xml version=*"1.0"* encoding=*"UTF-8"*?>

<beans xmlns=“http://www.springframework.org/schema/beans”

​ xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

​ xmlns:context=“http://www.springframework.org/schema/context”

​ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

​ <context:component-scan base-package=“com.atguigu”></context:component-scan>

3.5配置核心dispatcherServlet,在动态项目WEB-INF的web-xml中

​ springDispatcherServlet

​ org.springframework.web.servlet.DispatcherServlet

​ contextConfigLocation

​ classpath:springmvc.xml

​ 1

​ springDispatcherServlet

​ /

3.6配置xml中的mvc视图解析器

配置SpringMVC提交的视图解析器:

​ <bean class=“org.springframework.web.servlet.view.InternalResourceViewResolver”>

​ <property name=“prefix” value="/jsp/"/>

​ <property name=“suffix” value=".jsp"/>

视图解析器工作原理 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vTGBht1c-1574917565577)(file:///C:\Users\尚硅谷\AppData\Local\Temp\ksohtml15800\wps3.jpg)]

3.7 配置字符编码过滤器

​ CharacterEncodingFilter

​ org.springframework.web.filter.CharacterEncodingFilter

​ encoding

​ UTF-8

​ forceEncoding

​ true

​ CharacterEncodingFilter

​ /*

4. Spring-MVC处理请求及响应的方式

4.1视图页面请求(举例jsp)

//hello为请求地址,对应Controller标记类中被RequestMapping(value=”hello”)标记的方法

4.2 Controller注解类处理请求

* @Controller 表示当前类是一个控制器

@Controller

public class HelloController {

​ * @RequestMapping("/hello")

表示在SpringMVC中注册一个控制器,请求地址是http://ip:port/工程名/hello

​ @RequestMapping("/hello")

public String hello() {

​ System.out.println(“这是SpringMVC的hello程序”);

​ // “/jsp/target.jsp” 返回值表示要跳转的地址

​ // /,表示到http://ip:port/工程名/ 映射到WebContent目录

​ // “/jsp/target.jsp” 整个表示http://ip:port/工程名/jsp/target.jsp页面

​ // SpringMVC默认跳转使用的是转发

return “/jsp/target.jsp”;

5. RequestMapping注解详解

@RequestMapping(属性值)是给个方法配置一个访问地址,或者不同属性值.可能对应请求必要的参数或者请求方式,请求头信息等.

5.1 value属性(重点)

@RequestMapping(value="/hello")

表示映射当前这个请求方法的访问地址。

/ 表示到http://ip:port/工程名/ 映射到代码的WebContent目录

/hello 就表示到http://ip:port/工程名/hello

5.2 params属性

params是要求此请求的参数匹配

params=“username” 表示 请求地址必须带有username参数

params=“username=abc” 表示 请求参数中必须要有username,而且值还必须是abc

params=“username!=abc” 表示 1、请求参数中不能有username参数。2、有username参数,但值不能等于abc

params="!username" 表示 请求地址不能带有username参数

params= {“username!=abc”,"!password"} params可以有多个值,每个值之间是&&关系

以上条件表示要求:

( 请求地址中不能有username参数 || username参数值不能等于 abc && 不能有password参数 )

5.3 headers属性

可以限定请求头中的信息

* headers = “User-Agent=Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36”

​ * 表示限定浏览器必须是谷歌浏览器,而且版本还是Chrome/58.0.3029.110

​ @RequestMapping(value = “/header”, headers = “User-Agent=Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36”)

public String header() {}

5.4 method属性(次重点)

method=RequestMethod.GET 表示当前请求必须是GET请求才允许访问

​ * method=RequestMethod.POST 表示当前请求必须是POST请求才允许访问
可以在restful风格中设置不同的类型,标记增删改查方法

​ @RequestMapping(value="/method",method=RequestMethod.POST)

public String method() {}

5.5 RequestMapping注解标记类上

当我们在Controller控制器上添加一个@RequestMapping注解,并赋于value属性值的时候,相当于给类也加了一层访问的路径,多用来区别多个Controller类时不同类中方法地址重名,地址冲突。

比如:

@RequestMapping(value="/person")

@Controller

public class HelloController {

这个时候,HelloController中的方法都必须在原有请求地址路径前面加上/person。

5.6 通配符在RequestMapping中的使用

1、绝对匹配 value=精确的值

​ @RequestMapping(value = “/fun”)

​ public String fun() {}

2、? 问号 匹配资源路径

? 问号表示一个任意字符,只能匹配一个字符

​ @RequestMapping(value = “/fu?”)

public String fu?() {}

3、* 星号 匹配资源路径

* 星号 可以匹配任意个字符,可以匹配任意多个字符

​ @RequestMapping(value = “/fu*”)

​ public String fu21312312321() {}

4、? 问号 匹配一层目录

​ @RequestMapping(value = “/?/fun”)

​ public String fun3() {}

5、* 问号 匹配一层目录

​ @RequestMapping(value = “/*/fun”)

​ public String fun4() {}

6、** 星星号 匹配多层目录

​ @RequestMapping(value = “/**/fun”)

​ public String fun5() {}

6 Controller中接收请求参数(重点)

6.1原生API参数类型

6.1.1、HttpServletRequest类

​ @RequestMapping(value = “/param1”)

​ public String param1(HttpServletRequest request) {

​ System.out.println(“这是param1方法”);

​ System.out.println(request);

​ return “param”;

​ }

6.1.2、HttpSession类

​ @RequestMapping(value = “/param2”)

​ public String param2(HttpServletRequest request, HttpSession session) {

​ System.out.println(“这是param2方法”);

​ System.out.println(request);

​ System.out.println(session);

​ return “param”;

​ }

6.1.3、HttpServletResponse类

​ @RequestMapping(value = “/param3”)

​ public String param3(HttpServletRequest request, HttpSession session,

​ HttpServletResponse response) {

​ System.out.println(“这是param3方法”);

​ System.out.println(response);

​ System.out.println(request);

​ System.out.println(session);

​ return “param”;

​ }

6.2、普通类型入参

通过request对象获取(不推荐):

​ @RequestMapping(value="/param4")

public String param4(HttpServletRequest request) {

​ System.out.println(“这是param4方法”);

​ System.out.println(request.getParameter(“username”));

return “param”;

​ }

我们在Controller的目标方法上直接设置方法的参数。就可以直接传入请求参数的值。

​ @RequestMapping(value="/param5")

public String param5(String username) {

​ System.out.println(“这是param5方法”);

​ System.out.println(username);

return “param”;

​ }

要求:参数名必须和方法的参数名相匹配。

6.3 普通类型数组的参数

@RequestMapping(value = “/param6”)

public String param6(String[] hobbies) {

​ System.out.println(“这是param6方法”);

if (hobbies != null) {

for (String string : hobbies) {

​ System.out.println(string);

​ }

​ }

return “param”;

​ }

6.4普通类型使用@RequestParam入参

@RequestMapping(value = “/param7”)

public String param7(@RequestParam(value = “username”) String user) {

​ System.out.println(“这是param7方法”);

​ System.out.println(user);

return “param”;

​ }

@RequestParam(value = “username”) String user 表示SpringMVC会自动将请求过来的参数username的值。注入到方法参数user中。

默认情况下。@RequestParam(value = “username”)中要求的username参数必须要有值。否则就会报错误.

6.5 @RequestHeader获取请求头入参

​ @RequestMapping(value = “/param8”)

public String param8(@RequestHeader(value = “User-Agent”) String userAgent,

​ @RequestHeader(value = “Host”) String host) {

​ System.out.println(“这是param8方法”);

​ System.out.println(userAgent);

​ System.out.println(host);

return “param”;

​ }

6.6 @CookieValue获取Cookie值入参

@CookieValue注解获取cookie的值注入。

value中填写的是cookie的key值

​ @RequestMapping(value = “/param9”)

​ public String param9(@CookieValue(value = “JSESSIONID”) String jsessionid) {

​ System.out.println(“这是param9方法”);

​ System.out.println(jsessionid);

​ return “param”;

​ }

6.7一个Pojo对象类型的参数

要求:pojo对象自动入参的要求是客户端传递的参数名必须跟pojo对象的属性名对应上。

​ @RequestMapping(value="/param10")

public String param10(Person person) {

​ System.out.println(“这是param10方法”);

​ System.out.println(person);

return “param”;

​ }

6.8 对象中套对象(级联属性)

public class Book {

private String name;

private BigDecimal price;

public class Person {

private Integer id;

private String name;

private String phone;

private Integer age;

private Book book;

表单:

​ <form action="${ pageContext.request.contextPath }/param10">

​ id:<input type=“text” name=“id” />

​ name:<input type=“text” name=“name” />

​ phone:<input type=“text” name=“phone” />

​ age:<input type=“text” name=“age” />

​ book.name:<input type=“text” name=“book.name” />

​ book.price:<input type=“text” name=“book.price” />

​ <input type=“submit” />

@RequestMapping(value="/param10")

public String param10(Person person) {

​ System.out.println(“这是param10方法”);

​ System.out.println(person);

return “param”;

​ }

7 返回值的设置

7.1返回值是String时

7.1.1 默认情况

默认情况下,返回return字符串。会经过视图解析器做字符串前后缀拼接的操作,拼接完成后 默认做转发处理.

@Controller

public class ReturnController {

​ @RequestMapping(value = “/return1”)

public String return1() {

​ System.out.println(“这是return1方法”);

return “return”;

7.1.2 显式转发

显式转发的情况,在return 后面添加forward前缀,默认的视图解析器失效,/代表当前项目路径下

@RequestMapping(value = “/return2”)

public String return2() {

​ System.out.println(“这是return2方法”);

​ // 在返回的字符串前面 显示的 标注 forward:表示显示的转发

​ // 使用显示的转发,视图解析器就不会工作了

return “forward:/jsp/return.jsp”;

​ }

7.1.3 显式重定向

@RequestMapping(value = “/return3”)

public String return3() {

​ System.out.println(“这是return3方法”);

​ // 当我们在返回的字符串前面显示的加入redirect:表示强制使用重定向

​ // 只要是显示的声明使用转发或重定向,默认视图解析器将不在工作

return “redirect:/jsp/return.jsp”;

​ }

7.2 返回modelAndView

7.2.1 默认情况

默认的情况我们在ModelAndView中设置的ViewName就是默认转发的视图名。这个视图名会经过视图解析器拼接这符串后再转发。

@RequestMapping(value="/return4")

public ModelAndView return4() {

​ System.out.println(“这是return4方法”);

​ // ModelAndView 也可以设置返回的资源

​ ModelAndView modelAndView = new ModelAndView();

​ // 设置视图名

​ modelAndView.setViewName(“return”);

return modelAndView;

​ }

7.2.2显示转发

在返回的字符串前面 显示的 标注 forward:表示显示的转发,

使用显示的转发,视图解析器就不会工作了

@RequestMapping(value="/return5")

public ModelAndView return5() {

​ System.out.println(“这是return5方法”);

​ // ModelAndView 也可以设置返回的资源

​ ModelAndView modelAndView = new ModelAndView(“forward:/jsp/return.jsp”);

return modelAndView;

​ }

7.2.3显式重定向

当我们在返回的字符串前面显示的加入redirect:表示强制使用重定向,只要是显示的声明使用转发或重定向,默认视图解析器将不在工作

@RequestMapping(value="/return6")

public ModelAndView return6() {

​ System.out.println(“这是return6方法”);

​ ModelAndView modelAndView = new ModelAndView(“redirect:/jsp/return.jsp”);

return modelAndView;

​ }

7.3、返回void(不推荐在Controller中直接转发和重定向)(了解)

7.3.1、没有返回值的*默认情况*

一般在实际开发中。我们都是禁止使用如以上这种方式。使用默认的请求资源名做为默认转发的逻辑资源名。

如果有需要,都是使用String类型显示标明返回的逻辑名。也就是说以上代码应该写成为:

​ @RequestMapping(value="/return7")

public void return7() {

​ System.out.println(“return7方法”);

​ }

7.3.2、显示转发

​ @RequestMapping(value = “/return8”)

public void return8(HttpServletRequest request, HttpServletResponse response) {

​ System.out.println(“这是return8方法”);

try {

​ request.getRequestDispatcher("/jsp/return.jsp").forward(request,

​ response);

​ } catch (Exception e) {

​ e.printStackTrace();

​ }

7.3.3、显示重定向

​ @RequestMapping(value="/return9")

public void return9(HttpServletRequest request, HttpServletResponse response) {

​ System.out.println(“这是return9方法”);

try {

​ response.sendRedirect(request.getContextPath() + “/jsp/return.jsp”);

​ } catch (IOException e) {

​ e.printStackTrace();

7.3.4、直接输出响应数据

​ @RequestMapping(value="/return10")

public void return10(HttpServletResponse response) {

​ System.out.println(“这是return10方法”);

try {

​ response.getWriter().write(“this is the content of response!”);

​ } catch (IOException e) {

​ e.printStackTrace();

8. 数据在域中的输入保存

8.1、Request对象中保存数据(不推荐)

先在Controller的方法中添加一个HttpServletRequest对象

​ @RequestMapping(value="/requestScope")

public ModelAndView requestScope(HttpServletRequest request) {

​ System.out.println(“这是把数据保存到request域中—requestScope”);

​ request.setAttribute(“key1”, “value1”);

return new ModelAndView(“scope”);

8.2、Session域中保存数据

在Controller方法中,添加HttpSession对象

​ @RequestMapping(value="/sessionScope")

public ModelAndView sessionScope(HttpSession session) {

​ System.out.println(“这是把数据保存到session域中—sessionScope”);

​ session.setAttribute(“skey1”, “svalue1”);

return new ModelAndView(“scope”);

8.3、ServletContext域中保存数据

在Controller中的代码。在Controller的中获取SerlvetContext对象有两种方法,

一种是@Autowired注入,

一种是通过Session获取。

是通过@Autowired自动注入ServletContext对象

@Controller

public class ScopeController {

​ @Autowired

private ServletContext context;

通过HttpSession获取ServletContext对象

​ @RequestMapping(value = “/applicationScope”)

public ModelAndView applicationScope(HttpSession session) {

​ System.out.println(“这是把数据保存到ServletContext域中—applicationScope”);

​ session.getServletContext().setAttribute(“appKey1”, “appValue1”);

return new ModelAndView(“scope”);

​ }

8.4、Map或Model或ModelMap形式保存数据在request域中

在四个域中,我们使用最频繁的域就是request对象。往request域对象中,保存数据,还在以下的几种形式。

我们可以在Controller的方法中,添加Map类型的参数,或者是Model类型的参数。或者是ModelMap类型的参数。都可以直接用来保存域数据到Request对象中。

Map全类名是: java.util.Map

Model全类名是: org.springframework.ui.Model

ModelMap全类名是: org.springframework.ui.ModelMap

​ * BindingAwareModelMap 它叫隐含模型

​ * /\

​ * ||

​ * ExtendedModelMap -----实现>>>>>>Model接口

​ * /\

​ * ||

​ * ModelMap

​ * /\

​ * ||

​ * LinkedHashMap

​ * /\

​ * ||

​ * HashMap ------实现>>>>>> Map接口

​ @RequestMapping(value="/test")

public ModelAndView test(Map<String, Object> map,Model model,ModelMap modelMap) {

​ map.put(“key1”, “value1”);

​ model.addAttribute(“model1”, “modelValue1”);

​ modelMap.addAttribute(“modelMap1”, “modelMapValue1”);

​ System.out.println(map.getClass());

​ System.out.println(model.getClass());

​ System.out.println(modelMap.getClass());

return new ModelAndView(“scope”);

​ }

8.5、ModelAndView方式保存数据到request域中

把数据保存到ModelAndView中,springMVC保存到把数据保存到Request域中

​ @RequestMapping(value="/modelAndViewScope")

public ModelAndView modelAndViewScope() {

​ ModelAndView modelAndView = new ModelAndView(“scope”);

​ System.out.println(“这是modelAndViewScope方法”);

​ // 往ModelAndView中保存数据,同样SpringMVC也会保存到request域中

​ modelAndView.addObject(“modelAndView1”, “modelAndViewValue1”);

​ modelAndView.addObject(“modelAndView2”, “modelAndViewValue2”);

return modelAndView;

8.6、@SessionAttributes保存数据到****Session域中(*了解内容*,不推荐使用)

@SessionAttributes 注解可以标注在类上。它的作用是指定哪些数据可以保存到Session域中。

@SessionAttributes(value = { “key1”,“key2” }, types = { String.class, Book.class })

value属性,它表示把request域中key为key1,key2的键值对信息,也保存到Session中

types属性,它表示把request域中value类型为String.class或Book.class类型的键值对,也保存到Session中

8.7、@ModelAttribute注解

@ModelAttribute这个注解可以标注在方法和参数上。

@ModelAttribute三个常见作用:

1、被标注了@ModelAttribute的方法都会在Controller的目标方法之前执行。

2、目标方法的参数(JavaBean对象)会先从隐含模型中获取值传入。

3、@ModelAttribute被标注在目标的参数上,参数值会按照指定的key从隐含模型中获取值。

​ @ModelAttribute

public void abc(Map<String, Object> map) {

​ System.out.println(“我是@ModelAttribute标注的abc()方法”);

​ map.put(“book111”, new Book(“我是一个兵!”, new BigDecimal(99999999)));

​ }

​ * 目标方法中,如果有对象参数(非原生API,是那些pojo对象),它会先按照参数的类型取类名,然后首字母小写book,从隐含模型中取值注入。

​ @RequestMapping(value="/targetMethod")

public ModelAndView targetMethod(@ModelAttribute(“book111”)Book book) {

​ System.out.println(“targetMethod被调用了!”);

​ System.out.println(“目标方法中book的值是:” + book);

return new ModelAndView(“scope”);

​ }

9. Restful风格

9.1 Restful风格介绍

Restful 一种软件架构风格、设计风格,而不是标准.对于我们Web开发人员来说。就是使用一个url地址表示一个唯一的资源。然后把原来的请求参数加入到请求资源地址中。然后原来请求的增,删,改,查操作。改为使用HTTP协议中请求方式GET、POST、PUT、DELETE表示。

9.2 学习restful风格,明确2种方式

9.2.1传统的请求参数加入到请求地址

传统的方式是:

比如:http://ip:port/工程名/资源名?请求参数

举例:http://127.0.0.1:8080/springmvc/book?action=delete&id=1

restful风格是:

比如:http://ip:port/工程名/资源名/请求参数/请求参数

举例:http://127.0.0.1:8080/springmvc/book/1

请求的动作删除由请求方式delete决定

9.2.2 restful中请求方式GET、POST、PUT、DELETE分别表示查、增、改、删

GET请求 对应 查询

http://ip:port/工程名/book/1 HTTP请求GET 表示要查询id为1的图书

http://ip:port/工程名/book HTTP请求GET 表示查询全部的图书

POST请求 对应 添加

http://ip:port/工程名/book HTTP请求POST 表示要添加一个图书

PUT请求 对应 修改

http://ip:port/工程名/book/1 HTTP请求PUT 表示要修改id为1的图书信息

DELETE请求 对应 删除

http://ip:port/工程名/book/1 HTTP请求DELETE 表示要修改id为1的图书信息

9.2.3 SpringMVC中如何发送GET请求、POST请求、PUT请求、DELETE请求。

我们知道发起GET请求和POST请求,只需要在表单的form标签中,设置method=”get” 就是GET请求。

设置form标签的method=”post”。就会发起POST请求。而PUT请求和DELETE请求。要如何发起呢。

1、要有post请求的form标签

2、在form表单中,添加一个额外的隐藏域_method=”PUT”或_method=”DELETE”

3、在web.xml中配置一个Filter过滤器org.springframework.web.filter.HiddenHttpMethodFilter(注意,这个Filter一定要在处理乱码的Filter后面)

9.3 Restful的Controller实现

9.3.1在web.xml中配置HiddenHttpMethodFilter过滤器****如下:

必须放在字符过滤器下面

​ HiddenHttpMethodFilter

​ org.springframework.web.filter.HiddenHttpMethodFilter

​ HiddenHttpMethodFilter

​ /*

9.3.2 在view视图页面的配置

​ <input type=“hidden” name="_method" value=“DELETE” /> <input

​ type=“submit” value=“删除指定id的图书” />


​ <form action=“book/1” method=“post”>

​ <input type=“hidden” name="_method" value=“PUT” /> <input

​ type=“submit” value=“更新指定id的图书” />


9.3.3在Controller中的配置

@Controller

public class RestController {

​ @RequestMapping(value = “/book/1”, method = RequestMethod.DELETE)

public String deleteBook() {

​ System.out.println(“删除图书”);

return “redirect:/index.jsp”;

​ }

​ @RequestMapping(value = “/book/1”, method = RequestMethod.PUT)

public String updateBook() {

​ System.out.println(“更新图书”);

return “redirect:/index.jsp”;

​ }

9.3 Restful在高版本Tomcat中无法转发到jsp页面

出现4.5错误,解决方式如下:

方法一:修改jsp页面中的page指令isErrorPage=“true”,就可以访问了

<%@ page language=“java” contentType=“text/html; charset=UTF-8”

​ isErrorPage=“true”

​ pageEncoding=“UTF-8”%>

方法二:把转发改成为重定向 redirect:/

9.4 @PathVariable 路径参数获取

前面我们已经知道如何编写和配置restful风格的请求和控制器。

那么 现在的问题是。如何接收restful风格请求的参数。比如前面的id值。

第一种情况:

​ @RequestMapping(value = “/book/{id}”, method = RequestMethod.DELETE)

public String deleteBook(@PathVariable(value = “id”) int id) {

​ System.out.println(“删除图书 id ->” + id);

return “redirect:/index.jsp”;

​ }

/book/{id}

中{id}表示路径参数占位符

@PathVariable(value = “id”) int id

表示把请求路径book/{id} id所表示的值。注入到方法参数的int id中。

当@PathVariable注解中没有标记占位符名称的时候,默认使用对应的参数名做为路径参数的名称取值。

请记住:@PathVariable标记的路径变量,不能为空,必须有值

第二种情况:

​ @RequestMapping(value = “/book/{name}/{price}/”, method = RequestMethod.POST)

public String addBook(@PathVariable(“name”) String name,

​ @PathVariable(“price”) BigDecimal price) {

​ System.out.println(name);

​ System.out.println(price);

​ System.out.println(“添加图书”);

return “redirect:/index.jsp”;

​ }

在一次请求中,请求路径不是只能有一个路径参数。它可以有多个。

/book/{name}/{price}/

这里就表示这个book后面可以跟两个路径参数。{name}和{price}。

这两个路径参数分别注入到请求方法的 String name,和Bigdecimal price两个参数中

@PathVariable(“name”) String name,

表示把请求路径中的name路径参数注入到请求方法的name参数中。

@PathVariable(“price”) BigDecimal price

表示把请求路径中的price路径参数注入到请求方法的price参数中。

10. 了解内容

SpringMVC标签库(不常用)

自定义参数转换器

记住下面这个即可

@DateTimeFormat注解类型转换器

​ 我们除了可以像上面一样自定义类型转换器之外。还可以使用SpringMVC提供的注解@DateTimeFormat(pattern=“yyyy-MM-dd”)

public class Person {

private Integer id;

private String name;

​ @DateTimeFormat(pattern = “yyyy-MM-dd”)

private Date birthDate;

private String email;

private BigDecimal salary;

我们也可以像上面。在类的Date类型的属性上标上注解。就可以自动将String类型转换成为Date数据

下面的前端都可以完成验证,了解中的了解

较验器----参数的有效性验证Validate----Hibernate(需要的时候自查)

自定义错误信息的回显(需要的时候自查)

11. 文件上传

文件上传在SpringMVC中如何实现:

1、准备一个文件上传的表单

2、导入文件上传需要的jar包

commons-fileupload-1.2.1.jar、commons-io-1.4.jar

3、配置文件上传解析器 CommonsMultipartResolver

4、配置Controller控制器的代码

11.1 准备一个文件上传的表单

Enctype=”multipart/form-data”,这个格式固定,重点

​ method=“post” enctype=“multipart/form-data”>

​ 用户名:<input type=“text” name=“username”/>

​ 头像:<input type=“file” name=“photo”/>

​ <input type=“submit” />

11.2导入文件上传需要的jar包

下面是文件上传专用的核心包,其他Spring和Spring-MVC的jar包不在内

commons-fileupload-1.2.1.jar

commons-io-1.4.jar

commons-logging-1.1.3.jar

11.3配置文件上传解析器

​ <bean id=“multipartResolver”

​ class=“org.springframework.web.multipart.commons.CommonsMultipartResolver”>

​ <property name=“defaultEncoding” value=“UTF-8” />

11.4 文件上传Controller控制器

重点在方法的形参列表加上 MultipartFile 的对象

接收从页面上传获得的数据对象

@RequestMapping(value="/upload")

public String upload(String username,MultipartFile photo) {

​ System.out.println(“用户名:” + username);

​ //说明有上传的内容

​ // isEmpty判断是否为空

if (photo != null && !photo.isEmpty()) {

try {

// transferTo 将文件写入到硬盘位置

​ // getOriginalFilenameaqb

​ photo.transferTo(new File(“e:\” + photo.getOriginalFilename()));

​ } catch (IllegalStateException e) {

​ e.printStackTrace();

​ } catch (IOException e) {

​ e.printStackTrace();

​ }

​ }

return “forward:/index.jsp”;

​ }

12. 使用@ResponseBody返回数据转成json(重点)

12.1 使用的步骤如下

1、导入json相关的包到web工程中,导入以下jar包,实现无痛转换json

jackson-annotations-2.1.5.jar

jackson-core-2.1.5.jar

jackson-databind-2.1.5.jar

2、编写一个请求的方式接收请求,并返回数据对象

3、在方法上添加注解@ResponseBody自动将返回值json化

12.2 Controller中的代码

@ResponseBody

​ @RequestMapping(value = “/queryPersonById”)

public Person queryPersonById() {

return new Person(19, “name10”, new Date(), “azrail@126.com”,

new BigDecimal(100));

​ }

​ @ResponseBody

​ @RequestMapping(value = “/personList”)

public List personList() {

​ List list = new ArrayList();

for (int i = 0; i < 10; i++) {

​ list.add(new Person(i, “name” + i, new Date(), “azrail@126.com”,

new BigDecimal(100)));

​ }

return list;

​ }

12.3 使用@JsonFormat修改时间在json中的格式

第一种在属性上加注解@JsonFormat

@JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”, timezone = “GMT+8”)

​ private Date birthDate;

第二种在get方法上加注解 @JsonFormat

​ @JsonFormat(pattern=“yyyy-MM-dd HH:mm:ss”,timezone = “GMT+8”)

​ public Date getBirthDate() {

​ return birthDate;

​ }

@JsonFormat表示设置json转换格式。

pattern=“yyyy-MM-dd HH:mm:ss” 表示日期类型返回以 yyyy-MM-dd HH:mm:ss 格式 yyyy-MM-dd表示年月日,HH:mm:ss表示时分秒

timezone = “GMT+8” 表示时间为格林时间+8小时

13. 使用@RequestBody接收请求体数据

在HTTP协议中,我们知道,请求体只存在于POST请求中才有。

所以我们需要有一个表单。而且请求必须是post请求

13.1 准备一个post请求的表单

​ <form action="${pageContext.request.contextPath }/requestBody" method=“post”>

​ 用户名:<input type=“text” name=“username” />

​ 密码:<input type=“password” name=“password” />

​ <input type=“submit” />

13.2在Controller中添加一个方法接收请求体

​ * GET请求

​ * 1、请求行

​ * 2、请求头

​ * POST请求

​ * 1、请求行

​ * 2、请求头

​ * 空行

​ * 3、请求体(请求的参数)

// @RequestBody 它可以接收请求体的数据—请求体,只存在于post请求

​ @RequestMapping(value = “/requestBody”)

public String requestBody(@RequestBody String body) {

​ System.out.println(“请求体的全部内容:” + body);

return “forward:/index.jsp”;

​ }

14. 使用HttpEntity参数获取请求头和请求体**(了解)**

页面代码:

​ <form action="${pageContext.request.contextPath }/httpEntity" method=“post”>

​ 用户名:<input type=“text” name=“username” />

​ 密码:<input type=“password” name=“password” />

​ <input type=“submit” />

Controller代码:

​ @RequestMapping(value = “/httpEntity”)

public String httpEntity(HttpEntity httpEntity) {

​ System.out.println(“请求头:” + httpEntity.getHeaders());

​ System.out.println(“请求体:” + httpEntity.getBody());

return “forward:/index.jsp”;

​ }

15使用ResponseEntity文件下载 返回值操作 响应头和响应体

​ ResponseEntity返回值,设置信息返回给页面

@RequestMapping(value = “/download”)

public ResponseEntity<byte[]> download(HttpSession session) {

try {

​ ServletContext ctx = session.getServletContext();

​ // 斜杠(斜线)表示到http://ip:port/工程名/ 映射到代码的WebContent目录

​ InputStream is = ctx.getResourceAsStream("/imgs/e.jpg");

byte[] buffer;

​ buffer = new byte[is.available()];

​ //读文件数据

​ is.read(buffer);

​ is.close();

​ //获取需要下载的文件的数据类型

​ String mimeType = ctx.getMimeType("/imgs/e.jpg");

​ // 响应头

​ HttpHeaders httpHeaders = new HttpHeaders();

​ // 添加响应头,告诉客户端我回去的数据类型是什么

​ httpHeaders.add(“Content-Type”, mimeType);

​ httpHeaders.add(“Content-Disposition”, “attachment; filename=e.jpg”);

​ // 第一个参数是你要返回的数据–我们要实现文件下载,就需要把下载的文件字节内容都放body中

​ // 第二个参数是 响应头

​ // 第三个参数是你要返回的响应状态码和响应 状态描述 符

​ ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(

​ buffer, httpHeaders, HttpStatus.OK);

return responseEntity;

​ } catch (IOException e) {

​ // TODO Auto-generated catch block

​ e.printStackTrace();

​ }

return null;

​ }

16 HandlerInterceptor拦截器

HandlerInterceptor拦截器,可以拦截Controller控制方法

16.1 单个HandlerInterceptor拦截器的示例

1、编写一个类去实现HandlerInterceptor接口

2、到Spring的容器配置文件中去配置拦截器,让SpringMVC知道都拦截哪些目标方法

拦截器类实现代码:

public class FirstHandlerInterceptor implements HandlerInterceptor {

​ /**

​ * 在拦截到目标方法前调用

​ */

​ @Override

public boolean preHandle(HttpServletRequest request,

​ HttpServletResponse response, Object handler) throws Exception {

​ System.out.println(“FirstHandlerInterceptor – >>> preHandle” );

​ //return false不放行

​ //return true放行

return true;

​ }

​ /**

​ * 在目标方法执行之后执行。

​ */

​ @Override

public void postHandle(HttpServletRequest request,

​ HttpServletResponse response, Object handler,

​ ModelAndView modelAndView) throws Exception {

​ System.out.println(“FirstHandlerInterceptor – >>> postHandle” );

​ }

​ /**

​ * 在目标方法执行完。跳转页面渲染完之后

​ */

​ @Override

public void afterCompletion(HttpServletRequest request,

​ HttpServletResponse response, Object handler, Exception ex)

throws Exception {

​ System.out.println(“FirstHandlerInterceptor – >>> afterCompletion” );

​ }

}

MVC的xml文件中配置拦截的地址:

​ mvc:interceptors

​ mvc:interceptor

​ <mvc:mapping path="/hello"/>

<bean class=“com.atguigu.controller.FirstHandlerInterceptor” />

​ </mvc:interceptor>

​ </mvc:interceptors>

正常情况下,拦截器的执行顺序:

FirstHandlerInterceptor – >>> preHandle

目标方法执行…………

FirstHandlerInterceptor – >>> postHandle

页面渲染的代码

FirstHandlerInterceptor – >>> afterCompletion

16.2 单个拦截器异常时的执行顺序

一:目标方法前返回false的情况:

1、目标方法前执行 返回false

2、这是目标方法 不执行

3、目标方法之后 不执行

4、这是渲染页面 不执行

5、页面渲染完成! 不执行

二:目标方法前返回true的情况,目标方法异常

1、目标方法前执行 返回true

2、这是目标方法 异常

3、目标方法之后 不执行

4、这是渲染页面 渲染异常页面

5、页面渲染完成! 执行

三:目标方法前返回true的情况,目标方法后异常

1、目标方法前执行 返回true

2、这是目标方法 执行

3、目标方法之后 异常

4、这是渲染页面 渲染异常页面

5、页面渲染完成! 执行

四:目标方法前返回true的情况,渲染页面异常

1、目标方法前执行 返回true

2、这是目标方法 执行

3、目标方法之后 执行

4、这是渲染页面 异常

5、页面渲染完成! 执行

17. 异常处理

17.1 使用@ExceptionHandler注解处理异常

//@ExceptionHandler可以拦截到本Controller中的异常

​ @ExceptionHandler

public ModelAndView exceptionHandler(Exception e) {

​ System.out.println(“exceptionHandler — Exception”);

​ ModelAndView modelAndView = new ModelAndView(“forward:/error.jsp”);

​ modelAndView.addObject(“exception”, e);

return modelAndView;

​ }

​ //@ExceptionHandler可以拦截到本Controller中的异常

​ @ExceptionHandler

public ModelAndView exceptionHandler(RuntimeException e) {

​ System.out.println(“exceptionHandler — RuntimeException”);

​ ModelAndView modelAndView = new ModelAndView(“forward:/error.jsp”);

​ modelAndView.addObject(“exception”, e);

return modelAndView;

​ }

​ //@ExceptionHandler可以拦截到本Controller中的异常

​ @ExceptionHandler

public ModelAndView exceptionHandler(ArithmeticException e) {

​ System.out.println(“exceptionHandler — ArithmeticException”);

​ ModelAndView modelAndView = new ModelAndView(“forward:/error.jsp”);

​ modelAndView.addObject(“exception”, e);

return modelAndView;

​ }

在同一个Controller中可以有多个@ExceptionHandler标注的异常处理方法。

SpringMVC会优先选择异常信息精确的方法执行异常处理操作。

17.2 使用@ControllerAdvice注解处理异常

@ControllerAdvice它可以处理所有Controller中产生的异常

*/

@ControllerAdvice

public class ExceptionEHander2 {

​ @ExceptionHandler

public ModelAndView exceptionHandler(Exception e) {

​ System.out.println("@ControllerAdvice — Exception");

​ ModelAndView modelAndView = new ModelAndView(“forward:/error.jsp”);

​ modelAndView.addObject(“exception”, e);

return modelAndView;

​ }

​ @ExceptionHandler

public ModelAndView exceptionHandler(RuntimeException e) {

​ System.out.println("@ControllerAdvice — RuntimeException");

​ ModelAndView modelAndView = new ModelAndView(“forward:/error.jsp”);

​ modelAndView.addObject(“exception”, e);

return modelAndView;

​ }

​ @ExceptionHandler

public ModelAndView exceptionHandler(ArithmeticException e) {

​ System.out.println("@ControllerAdvice — ArithmeticException");

​ ModelAndView modelAndView = new ModelAndView(“forward:/error.jsp”);

​ modelAndView.addObject(“exception”, e);

return modelAndView;

​ }

17.3 异常处理优先顺序

在局部异常处理和全局异常处理同时存在的时候,优先顺序是:

本类异常处理,优先其他类异常处理,在本类中,精准异常处理优先.

17.4 使用(xml中配置异常处理) SimpleMappingExceptionResolver类映射异常跳转

​ <bean class=“org.springframework.web.servlet.handler.SimpleMappingExceptionResolver”>

​ <property name=“exceptionMappings”>

​ <!–

​ key写上异常全类名

​ 在prop标签中填写那批的跳转地址

​ -->

​ <prop key=“java.lang.Exception”>forward:/error.jsp

​ <prop key=“java.lang.RuntimeException”>forward:/error.jsp

​ <prop key=“java.lang.ArithmeticException”>forward:/error.jsp

​ <prop key=“java.lang.NullPointerException”>forward:/null.jsp

ollerAdvice它可以处理所有Controller中产生的异常**

*/

@ControllerAdvice

public class ExceptionEHander2 {

​ @ExceptionHandler

public ModelAndView exceptionHandler(Exception e) {

​ System.out.println("@ControllerAdvice — Exception");

​ ModelAndView modelAndView = new ModelAndView(“forward:/error.jsp”);

​ modelAndView.addObject(“exception”, e);

return modelAndView;

​ }

​ @ExceptionHandler

public ModelAndView exceptionHandler(RuntimeException e) {

​ System.out.println("@ControllerAdvice — RuntimeException");

​ ModelAndView modelAndView = new ModelAndView(“forward:/error.jsp”);

​ modelAndView.addObject(“exception”, e);

return modelAndView;

​ }

​ @ExceptionHandler

public ModelAndView exceptionHandler(ArithmeticException e) {

​ System.out.println("@ControllerAdvice — ArithmeticException");

​ ModelAndView modelAndView = new ModelAndView(“forward:/error.jsp”);

​ modelAndView.addObject(“exception”, e);

return modelAndView;

​ }

17.3 异常处理优先顺序

在局部异常处理和全局异常处理同时存在的时候,优先顺序是:

本类异常处理,优先其他类异常处理,在本类中,精准异常处理优先.

17.4 使用(xml中配置异常处理) SimpleMappingExceptionResolver类映射异常跳转

​ <bean class=“org.springframework.web.servlet.handler.SimpleMappingExceptionResolver”>

​ <property name=“exceptionMappings”>

​ <!–

​ key写上异常全类名

​ 在prop标签中填写那批的跳转地址

​ -->

​ <prop key=“java.lang.Exception”>forward:/error.jsp

​ <prop key=“java.lang.RuntimeException”>forward:/error.jsp

​ <prop key=“java.lang.ArithmeticException”>forward:/error.jsp

​ <prop key=“java.lang.NullPointerException”>forward:/null.jsp

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值