SpringMVC中组件学习|视图解析|MVC运行过程|简单项目搭建

文章目录

SpringMVC

一.环境准备

1.建立maven下的web工程

如果出现Cannot resolve plugin org.apache.maven.xxxxx等类似在pom.xml中出现的错误,请到本地仓库下删除相应jar包的文件夹,然后点击刷新

2.在pom.xml加入相关jar包依赖

		<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.3.3</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.3.3</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.3.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.24</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.3</version>
        </dependency>

3.创建web工程完成目录

  • 在main目录下创建java与resources
    注意:如果这里的java不是蓝色的,需要自己去目录结构里面设置
    在这里插入图片描述

4.在web.xml中配置DispatcherServlet类

  • 说明:这个类DispatcherServlet就是区别与普通MVC的最大特征,这是一个前置的控制器,会比servlet更早的拦截下请求,然后进行分发处理提高效率。
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--一定要配置初始化,来让springMVC.xml扫描全局注解-->
    <!-- 配置DispatcherServlet的初始化參數:设置文件的路径和文件名称 -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springMVC.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <!--/*和/都是拦截所有请求,/*比/的范围更大-->
    <url-pattern>/</url-pattern>
  </servlet-mapping>

5.在resources目录下创建springMVC的xml文件

  • 切记一定要配置扫描全部包注解的标签

在这里插入图片描述

6.配置tomcat服务器

二.正式进入SpringMVC的世界

1.SpringMVC下的第一个helloWorld工程

  • Java类的书写
/**
 * 告诉springMVC这是一个处理器,可以处理请求
 * @Controller,表示那个组件是控制器
 */
@Controller
public class MyFirstController {
    /**
     *  /代表从当前目录下开始,"/hello"就是处理当前目录下的请求
     */
    @RequestMapping(value = "/hell?")
    public String myFirstRequest(){
        System.out.println("请求收到了!");
        /*success为跳转成功的页面,写成这样的省略模式需要在springMVC下进行相应配置   */     
        return "success";
    }
}
  • index.jsp的书写
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello World!</h2>
<a href="hello">helloWorld</a>
</body>
</html>
  • 配置springMVC的xml文件在标签下
 <!--开启注解扫描-->
    <context:component-scan base-package="com.lhjitem"></context:component-scan>
    <!--配置映射(视图)解析器:如何将控制器返回的结果字符串,转换为一个物理的视图文件-->
    <bean id="irvr" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--prefix(前缀)是代表跳转页面文件的所在目录-->
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <!--suffix(后缀)表示文件的后缀名-->
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--配置springmvc框架注解的支持-->
    <mvc:annotation-driven></mvc:annotation-driven>

2.SpringMVC中最强大的注解:@RequestMapping

2.1RequestMapping的属性
  1. value及path(默认):
    作用:
  •   就是告诉SpringMVC;这个方法用来处理什么请求;
    
  •  这个/是可以省略,即使省略了,也是默认从当前项目下开始;
    
  •  习惯加上比较好    /hello  /hello
    
  •  还可以进行模糊查询 :URL地址可以写模糊的通配符:?:能替代任意一个字符(0个多个都不行;)、*:能替代任意多个字符,和一层路径、**:能替代多层路径
    
  •  模糊和精确多个匹配情况下,精确优先
    
  1. method:限定请求方式
    据我们所知HTTP协议中请求方式有:
  • 【GET】, HEAD, 【POST】, PUT, PATCH, DELETE, OPTIONS, TRACE
    
    作用:
  •  method=RequestMethod.POST:只接受这种类型的请求,默认是什么都可以;
    
  •   不是规定的方式报错:4xx:都是客户端错误
    
  •   405 - Request method 'GET' not supported
    
  1. params:规定请求参数
    param1: 表示请求必须包含名为 param1 的请求参数
  •   	eg:params={"username"}:
    
  •   		发送请求的时候必须带上一个名为username的参数;没带都会404
    

    !param1: 表示请求不能包含名为 param1 的请求参数

  •   	eg:params={"!username"}
    
  •   	发送请求的时候必须不携带上一个名为username的参数;带了都会404
    

    param1 != value1: 表示请求包含名为 param1 的请求参数,但其值不能为 value1

  •   	eg:params={"username!=123"}
    
  •   	发送请求的时候;携带的username值必须不是123(不带username或者username不是123)
    

    {“param1=value1”, “param2”}: 请求必须包含名为 param1 和param2 的两个请求参数,且 param1 参数的值必须为 value1

  •   	eg:params={"username!=123","pwd","!age"}
    
  •   		请求参数必须满足以上规则;
    
  •   		请求的username不能是123,必须有pwd的值,不能有age
    
  1. headers:规定请求头;也和params一样能写简单的表达式
/**
	 * User-Agent:浏览器信息;
	 * 让火狐能访问,让谷歌不能访问
	 * 
	 * 谷歌:
	 * User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
	 * 火狐;
	 * User-Agent	Mozilla/5.0 (Windows NT 6.3; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0
	 * @return
	 * 
	 */
	@RequestMapping(value="/handle04",headers={"User-Agent=Mozilla/5.0 (Windows NT 6.3; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0"})
	public String handle04(){
		System.out.println("handle04....");
		return "success";
	}
  1. consumes:只接受内容类型是哪种的请求,规定请求头中的Content-Type
  2. produces:告诉浏览器返回的内容类型是什么,给响应头中加上Content-Type:text/html;charset=utf-8

3.SpringMVC中@PathVariable注解的使用

3.1说明

用来接收占位符的值,以达到显示不同的种类

3.2获取不同图书实例,结合Rest理解
@Controller
public class BookController {
    /**
     * 处理查询图书请求
     * @param id
     * @return
     */
    @RequestMapping(value="/book/{bid}",method=RequestMethod.GET)
    public String getBook(@PathVariable("bid")Integer id) {
        System.out.println("查询到了"+id+"号图书");
        return "success";
    }

4.SpringMVC中Rest风格的URL地址

4.1说明

系统希望以非常简洁的URL地址来发请求;

4.2怎样表示对一个资源的增删改查用请求方式来区分
  • 传递的URL类似于这样:
    /getBook?id=1 :查询图书
    /deleteBook?id=1:删除1号图书
    /updateBook?id=1:更新1号图书
    /addBook :添加图书

  • Rest推荐;
    url地址这么起名; /资源名/资源标识符
    /book/1 :GET-----查询1号图书
    /book/1 :PUT------更新1号图书
    /book/1 :DELETE-----删除1号图书
    /book :POST-----添加图书
    系统的URL地址就这么来设计即可;
    简洁的URL提交请求,以请求方式区分对资源操作;

  • 问题:
    从页面上只能发起两种请求,GET、POST;
    其他的请求方式没法使用;

5.SpringMVC中获取请求参数

5.1最简单的获取方法

直接给方法入参上写一个和请求参数名相同的变量。这个变量就来接收请求参数的值;
* 带:有值,没带:null;

@Controller
public class Request {
    @RequestMapping("/hello")
    public String test01(String username){
        System.out.println("这个变量的值:" + username);
        return "success";
    }
}

在这里插入图片描述

在这里插入图片描述

5.2请求参数的注解
  • @RequestParam:获取请求参数的;参数默认是必须带的;
    = request.getParameter(“user”)
  • @RequestHeader:获取请求头中某个key的值;
    = request.getHeader(“User-Agent”);
  • @CookieValue:获取某个cookie的值;

这三个注解都有三个属性

  • value():指定要获取的参数的key
  • required():这个参数是否必须的
  • defaultValue():默认值。没带默认是null;
@RequestMapping("/hello")
    public String test02(@RequestParam(value = "username",required = false,defaultValue = "这是默认值") String username,
                         @RequestHeader(value = "User-Agent",required = false,defaultValue = "这是默认值") String userAgent,
                         @CookieValue(value = "JSESSIONID",required = false)String jid){
        System.out.println("这个变量的值:" + username);
        System.out.println("请求头中浏览器的信息:" + userAgent);
        System.out.println("cookie中的jid的值"+jid);
        return "success";
    }
5.3请求参数为一个pojo对象

SpringMVC会自动的为这个POJO进行赋值

  1. 将POJO中的每一个属性,从request参数中尝试获取出来,并封装即可;
  2. 还可以级联封装;属性的属性
  3. 请求参数的参数名和对象中的属性名一一对应就行
@RequestMapping("/person")
    public String test03(Person person){
        System.out.println("这个人是:" + person);
        return "success";
    }
<form action="person" method="post">
id:<input type="text" name="id"/><br>
姓名:<input type="text" name="name"/><br>
年龄:<input type="text" name="age"/><br>
性别:<input type="text" name="sex"/><br>
民族:<input type="text" name="national"/><br>
    <input type="submit" value="提交">
</form>

运行结果:
在这里插入图片描述

6.SpringMVC中发送响应参数(Map、Model和ModelMap这三者的关系图)

6.1获取方式
  1. 可以在方法处传入Map、或者Mode(接口)或者ModelMap。给这些参数里面保存的所有数据都会放在请求域(request)中。Map、或者Mode(接口)或者ModelMap这三者的关系图如下:
    在这里插入图片描述

  2. 方法的返回值可以变为ModelAndView类型,既包含视图信息(页面地址)也包含模型数据(给页面带的数据;而且数据是放在请求域中;
    request、session、application;

  3. SpringMVC提供了一种可以临时给Session域中保存数据的方式;
    使用一个注解 @SessionAttributes(只能标在类上)

  4. ModelAttribute注解;

6.2简单获取Map、Model、ModelMap中的value
	@RequestMapping("/hello1")
    public String test01(Map<String ,String> map){
        map.put("key1","value1");
        return "success";
    }
    
	@RequestMapping("/hello2")
    public String test02(Model model){
        model.addAttribute("key1","value1");
        return "success";
    }

    @RequestMapping("/hello3")
    public String test03(ModelMap map){
        map.addAttribute("key1","value1");
        return "success";
    }
pageContext:${pageScope.key1}<br>
request:${requestScope.key1}<br>
session:${sessionScope.key1}<br>
application:${applicationScope.key1}<br>

页面显示结果(都放在了request域中):
在这里插入图片描述

6.3方法的返回值可以变为ModelAndView类型
6.3.1使用说明

既包含视图信息(页面地址)也包含模型数据(给页面带的数据);

  •  	而且数据是放在请求域中;
    
  •  	request、session、application;
    
6.3.2具体应用
/**
    * 返回值是ModelAndView;可以为页面携带数据
    * @return
    */
   @RequestMapping("/hello4")
   public ModelAndView test04(){
       //之前的返回值我们就叫视图名;视图名视图解析器是会帮我们最终拼串得到页面的真实地址;
       //ModelAndView mv = new ModelAndView("success");
       ModelAndView mv = new ModelAndView();
       mv.setViewName("success");
       mv.addObject("key1", "你好哦!");
       return mv;
   }
6.3.3运行结果

在这里插入图片描述

6.4SpringMVC提供了一种可以临时给Session域中保存数据的方式
6.4.1使用说明

使用一个注解 @SessionAttributes(只能标在类上)
推荐@SessionAttributes就别用了,可能会引发异常;

如果不想引发异常(在隐含模型中找不到对象信息,就会自动去session域中找,而session此时可能也没有
所以这个异常也就出现了)。
我们需要注意两点:

  • 隐含模型中有@SessionAttributes标注的属性
  • 如果隐含模型中找不到,那么一定要保证session域中要有

给session中放数据请使用原生API;

6.5ModelAttribute注解;
6.5.1使用说明

当我们进行全字段的数据库更新操作时,例如更新书籍的操作,据我们所知,在更新书籍时是不可能让我们修改书名和作者的。
但由于是全字段操作,SpringMVC会帮助我们创建一个新的JavaBean对象,然后将全字段的信息传入进去,但由于书名和作者我们无法修改,所以我们不会设置这两项的值。
但此时这个新对象,由于我们未传入数据,所以这两项的值为null。然后会覆盖掉数据库里面的信息,这是我们不希望看到的。

这个ModelAttribute的注解的作用是不让SpringMVC使用自己创建的新对象,而是直接使用数据库中的那个已经封装好的对象来供我们修改,这样就不会对关键数据造成影响

这只是ModelAttribute的其中之一的用处

6.5.2具体用法
  • ModelAttribute:
    •  参数:取出刚才保存的数据
      
    •  方法位置:这个方法就会提前于目标方法先运行;
      
    •  	1)我们可以在这里提前查出数据库中图书的信息
      
    •  	2)将这个图书信息保存起来(方便下一个方法还能使用)
      
  • 通过map储存到的人信息,取出来然后对个别信息进行修改。在提交,这样就不会把源数据的关键信息覆盖掉
/**
	 * 可以告诉SpringMVC不要new这个book了我刚才保存了一个book;
	 * 哪个就是从数据库中查询出来的;用我这个book?
	 * 
	 *  
	 * 同都是BindingAwareModelMap
	 * @param book
	 * @return
	 */
	@RequestMapping("/updateBook")
	public String updateBook(@RequestParam(value="author")String author,
			@ModelAttribute("haha")Book book
			){
		Object haha = model.get("haha");
		//System.out.println("传入的model:"+model.getClass());
		System.out.println("页面要提交过来的图书信息:"+book);
		return "success";
	}
  • 使用一个方法把一个map保存到底层BlindingAwareModelMap中去(代替从数据库取pojo对象的过程),然后全局的ModelAttribute都能使用,这个过程称为在隐含模型中取对象信息
 * 这个传入map的用法是ModelAttribute最常用的用法
	 * @ModelAttribute* 		参数:取出刚才保存的数据
	 * 		方法位置:这个方法就会提前于目标方法先运行;
	 * 			1)我们可以在这里提前查出数据库中人的信息
	 * 			2)将这个人信息保存起来(方便下一个方法还能使用)
	 * 
	 * 参数的map:BindingAwareModelMap
	 */
	@ModelAttribute
	public void hahaMyModelAttribute(Map<String, Object> map){
		
		Person person = new Person(1,"XXX",20,"男","汉族");
		System.out.println("数据库中查到的人是:"+person);
		map.put("haha", book);
		System.out.println("modelAttribute方法...查询了图书并给你保存起来了...他用的map的类型:"+map.getClass());
	}

7.SpringMVC中视图解析

7.1说明

视图相关的执行途径都是接口,提供超高定制化的view处理,自己根据里面的抽象方法可定制来完成自己的需求

一句话:
视图解析器(ViewResolver)只是为了得到视图对象;视图对象才能真正的转发(将模型数据全部放在请求域中)或者重定向到页面
视图对象才能真正的渲染视图;

7.2视图解析流程

在这里插入图片描述

7.3视图国际化
7.3.1说明

当你导入jstl或者在springMVC.xml中配置了国际化,当解析视图时会自动创建一个jstlView对象,这是InternalResourceViewResolver
的子类

7.4问题

访问工程目录下的首页处理信息(CRUD),这是我们可以添加一个标签,让其经过spring的封装
<jsp:forward page=“所要处理的请求名”/>,然后直接转发到我们请求方法里面的那个jsp页面

8.SpringMVC中数据校验

8.1说明

数据校验:我们提交的数据必须是合法的
前端校验:js+正则表达式;
后端校验:由于浏览器可以禁用js,所以对于关键数据只进行前端校验是不行的,我们必须前端+后端

8.2数据校验流程图

在这里插入图片描述

8.3数据校验注解
8.3.1 JSR 303

这是一个提供校验的的规范,具体实现的其规范的是一个第三方的框架,名为:Hibernate Validator

8.3.2 Hibernate Validator
  1. 加入jar包
    在这里插入图片描述在这里插入图片描述
  2. 注解使用
    对封装对象校验的实例(原生标签显示错误信息的写法也在里面):
@RequestMapping(value = "/emp", method = RequestMethod.POST)
	public String addEmp(@Valid Employee employee, BindingResult result,
			Model model) {
		System.out.println("要添加的员工:" + employee);
		// 获取是否有校验错误
		boolean hasErrors = result.hasErrors();
		Map<String, Object> errorsMap = new HashMap<String, Object>();
		if (hasErrors) {
			List<FieldError> errors = result.getFieldErrors();
			for (FieldError fieldError : errors) {
				
				System.out.println("错误消息提示:" + fieldError.getDefaultMessage());
				System.out.println("错误的字段是?" + fieldError.getField());
				System.out.println(fieldError);
				System.out.println("------------------------");
				errorsMap.put(fieldError.getField(),
						fieldError.getDefaultMessage());
			}
			model.addAttribute("errorInfo", errorsMap);
			System.out.println("有校验错误");
			return "add";
		} else {
			employeeDao.save(employee);
			// 返回列表页面;重定向到查询所有员工的请求
			return "redirect:/emps";
		}
	}

在jsp页面做相应配置就可让用户看到自己那个地方有错误

<!--原生标签用的原理是,将错误信息保存到map中,然后通过用一个隐含模型中调用错误信息-->
	lastName:<form:input path="lastName"/>
		<form:errors path="lastName"/>-->${errorInfo.lastName }
		<!--springMVC标签-->                <!--原生表单标签-->
		<br/>
	email:<form:input path="email"/>
		<form:errors path="email"/>-->${errorInfo.email }
		<br/>

这个框架所支持的注解十分多切强大,建议阅读这个博客了解

Hibernate Validator注解大全

9.mvc:annotation-driven标签的解析

9.1请求有问题时
<mvc:default-servlet-handler/> 
<mvc:annotation-driven/>

当初出现问题时会依次配置这两个标签

  • 两个如果能没配,动态资源(@RequestMapping映射的资源)能访问,静态资源(.html,.js,.img)不能访问。
    原因:handlerMap中的DefaultAnnotationHandlerMapping没有保存静态资源映射的请求,
    在这里插入图片描述

  • 加上<'mvc:default-servlet-handler/>,不加<'mvc:annotation-driven/> ,静态资源加载出来,动态资源又加载不出来了。
    原因:DefaultAnnotationHandlerMapping被替代,SimpleUrlHandlerMapping把所有请求都映射给tomcat;
    在这里插入图片描述

  • 加上<'mvc:default-servlet-handler/>,和加上<'mvc:annotation-driven/>;两者皆能访问。
    原因:有SimpleUrlHandlerMapping静态资源没问题,handlerMappings中多出了一个RequestMappingHandlerMapping,所以动态资源可以访问
    在这里插入图片描述

9.SpringMVC中数据格式化

9.1日期格式化
9.1.1注解
  • @DateTimeFormat()
9.1.2注解属性
  • pattern:规定日期显示的格式,例如:yyyy-MM-dd
9.1.3注意

一旦使用注解配置好后格式,以后的日期格式都要遵从这个

9.2数据格式化
9.2.1注解
  • @NumberFormat()
9.2.2注解属性
  • pattern:规定数据的格式,例如:##,###,###.##
9.2.3注意

实例:传入工资20000.98–>经过格式化20,000.98
一旦使用注解配置好后格式,以后的数据格式都要遵从这个

10.SpringMVC中数据国际化

10.1说明

书接8中的数据校验问题,如果出现错误提示用户那个地方出现问题的信息,对这个信息可以进行国际化显示
但如果没有国际化需求,在每个Hibernate Validator注解中都有一个message属性来直接显示错误信息

10.2步骤
  1. 创建两个properties文件专门存放错误信息的国际化配置(配置时还可以对相对应的注解属性信息进行显示)
    在这里插入图片描述在这里插入图片描述

  2. 然后根据那个字段错误进行配置(如果对同一字段的四种类型都做了配置,那么会精确优先)
    字段错误的分类:
    在这里插入图片描述由上及下逐渐模糊

  3. 在springMVC中交给spring控制

<!-- 管理国际化资源文件,同理id必须是messageSource,理由是隐含模型代码中调用错误文件时的对象名就是这个 -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="errors"></property>
    </bean>

11.SpringMVC中文件上传

11.1配置
  1. 下载上传所需的jar包
    在这里插入图片描述2. 在springMVC.xml中配置九大组件的下载组件
    在这里插入图片描述
11.2具体实现

单文件上传

@Controller
public class UploadFile {
    @RequestMapping("/uploadFile")
    public String test01(@RequestParam(value = "username",required = false)
                                     String username,
                         @RequestParam("lalala") MultipartFile file,
                         Model model) throws IOException {
        System.out.println("文件的名字"+file.getOriginalFilename());
        System.out.println("文件的大小"+file.getSize());
        //文件保存
        try {
            file.transferTo(new File("D:\\JAVA_Files\\"+file.getOriginalFilename()));
            model.addAttribute("msg","文件上传成功!");
        } catch (Exception e) {
            model.addAttribute("msg","文件上传失败!"+e.getMessage());
        }
        return "forward:/index.jsp";
    }
}

多文件上传

@Controller
public class UploadFiles {
    /*多文件上传*/
    @RequestMapping("/uploadFiles")
    public String test01(@RequestParam(value = "username",required = false) String username,
                         @RequestParam("lalala") MultipartFile[] files,
                         Model model){

        for (MultipartFile file : files) {
            if(!file.isEmpty()){
                try {
                    file.transferTo(new File("D:\\JAVA_Files\\"+file.getOriginalFilename()));
                    model.addAttribute("msg","文件上传成功!");
                } catch (Exception e) {
                    model.addAttribute("msg","文件上传失败!"+e.getMessage());
                }
            }
        }
        return "forward:/index.jsp";
    }
}

12.SpringMVC拦截器

12.1说明

SpringMVC提供了拦截器机制;允许运行目标方法之前进行一些拦截工作,或者目标方法运行之后进行一些其他处理;
Filter:javaWeb(适用范围大)
HandlerInterceptor:SpringMVC(适用范围小)

什么时候用Filter:
简单需求就用Filter
什么时候用HandlerInterceptor:
如果某些功能需要用到其他组件来完成,较难时就用拦截器

HandlerInterceptor接口的三个重写方法:

  • preHandle:在目标方法运行之前调用;返回boolean;return true;(chain.doFilter())放行; return false;不放行
  • postHandle:在目标方法运行之后调用:目标方法调用之后
  • afterCompletion:在请求整个完成之后;来到目标页面之后;chain.doFilter()放行;资源响应之后;
12.2单拦截器流程

正常执行流程
拦截器的preHandle–>目标方法–>拦截器postHandle–>页面–>拦截器的afterCompletion;
在这里插入图片描述
异常执行流程
preHandle只要不放行,其他都不执行
在这里插入图片描述

12.3多拦截器流程

正常执行流程在这里插入图片描述在这里插入图片描述
异常流程
前提:一号放行,二号有异常
已经放行了的拦截器的afterCompletion总会执行;
在这里插入图片描述

在这里插入图片描述

13.SpringMVC国际化

13.1说明

在springMVC中大概有三种配置切换国际化的方法:

  1. 自定义区域信息解析器 (LocaleResolver)
  2. 使用SessionLocaleResolver实现点击切换:区域信息是从session中获取。
  3. SessionLocaleResolver配合Locale使用
13.2不同方法前都要的步骤
  • 先写不同语言的properties文件
  • 依旧在springMVC.xml中配置
<!-- 管理国际化资源文件,同理id必须是messageSource,理由是隐含模型代码中调用错误文件时的对象名就是这个 -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <!--value值就是你配置文件的前缀名-->
        <property name="basename" value="i18n"></property>
    </bean>
13.3自定义区域信息解析器 (LocaleResolver)
  1. 继承LocaleResolver接口重写两个方法:resolveLocale(解析返回locale)、setLocale(修改locale)
public class MyLocaleResolver implements LocaleResolver {
    @Override
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
        Locale l = null;
        //根据页面带的参数值来设置区域信息
        String locale = httpServletRequest.getParameter("locale");
        if(!locale.equals("") && locale!=null){
            //发过来的参数一般都是 zh_CN,前面是语言,后面是地区
            l =new Locale(locale.split("_")[0], locale.split("_")[1]);
        }else {
            //如果没带位置区域信息,我们就默认一个,就用浏览器带的请求头中的,即浏览器默认的
            l = httpServletRequest.getLocale();
        }
        return l;
    }

    @Override
    public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
        throw new UnsupportedOperationException(
                "Cannot change HTTP accept header - use a different locale resolution strategy");
    }
}
  1. 在springMVC.xml中配置自定义区域信息解析器
<!--配置自定义区域解析器-->
    <bean id="localeResolver" class="com.lhjitem.international.MyFirstLocaleResolver"></bean>
13.5显示结果

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

13.4出现的问题
  1. 当出现页面国际化信息有??乱码时,就是springMVC搜索不到相对应的properties文件,但前一天还是正常的,经过改名后恢复正常。

13.SpringMVC异常处理

13.1说明

默认情况下异常处理器(HandlerExceptionResolver)有三个

  • ExceptionHandlerExceptionResolver
  • ResponseStatusExceptionResolver
  • DefaultHandlerExceptionResolver
    如果三个处理器依次都处理不了的异常直接抛给tomcat显示异常
  • SimpleMappingExceptionResolver:这个异常处理器需要自己在springMVC中配置才能使用,指定发生异常时去什么页面

同理如果四个都设置了同一个异常的处理,执行顺序是从上到下的优先级

13.2异常注解
  • @ExceptionHandler
    在一个类中的某个方法上面加,即为告诉springMVC这个方法专门处理这个类中的‘’XX‘’异常
    具体处理什么异常在value属性中配置
    可以专门写个错误页面,当发生错误时跳转进错误页面告诉用户什么地方发生错误了
  • @ControllerAdvice
    当专门写了一个各种异常处理的集合类,用于告诉springMVC这个类专门处理异常
  • @ResponseStatus
    给自定义某个特定的异常类上标注的
13.3具体实现
/**
	 * 告诉SpringMVC这个方法专门处理这个类发生的异常 1、给方法上随便写一个Exception,用来接受发生的异常
	 * 2、要携带异常信息不能给参数位置写Model; 3、返回ModelAndView就行了;
	 * 4、如果有多个@ExceptionHandler都能处理这个异常,精确优先 5、全局异常处理与本类同时存在,本类优先;
	 */
//	@ExceptionHandler(value = { Exception.class })
//	public ModelAndView handleException01(Exception exception) {
//		System.out.println("本类的:handleException01..." + exception);
//		//
//		ModelAndView view = new ModelAndView("myerror");
//		view.addObject("ex", exception);
//		// 视图解析器拼串
//		return view;
//	}

三.SpringMVC下WEB的三大组件的各种配置

1.HiddenHttpMethodFilter解决从页面上只能发起两种请求,GET、POST

1.1说明

由于前面我们可以知道增删改查都是使用一个对应的请求来辨别,但是在jsp中只提供了两种请求方式get和post,所有我们只能将删除和更新操作通过过滤器来让servlet来辨别是什么操作

从页面发起PUT、DELETE形式的请求?Spring提供了对Rest风格的支持

SpringMVC中有一个Filter;他可以把普通的请求转化为规定形式的请求;配置这个filter;

1.2在web.xml中配置HiddenHttpMethodFilter

注意:要配置在标签前面

	<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>
1.3如何发其他形式请求?

按照以下要求:

  1. 创建一个post类型的表单
  2. 表单项中携带一个_method的参数
  3. 这个_method的值就是DELETE、PUT
<!-- 发送DELETE请求 -->
<form action="book/1" method="post">
    <input name="_method" value="delete"/>
    <input type="submit" value="删除1号图书"/>
</form><br/>

<!-- 发送PUT请求 -->
<form action="book/1" method="post">
    <input name="_method" value="put"/>
    <input type="submit" value="更新1号图书"/>
</form><br/>
1.4出现的问题

全部配置好后,如果在delete和put请求上面出现了405的问题,造成原因是Tomcat版本太高(博主用的是9.0.45)
在这里插入图片描述

  • 第一种解决方案:请在处理页面的Java代码方法上加上@ResponseBody注解,方可解决,
  • 第二种解决方案:在跳转后的页面的jsp的头标签中加入isErrorPage="true
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>

2.提交数据乱码问题

  1. 请求乱码:
  • GET请求(所有请求的信息都带在url中,服务器一收到就开始解析):改server.xml;在8080端口处URIEncoding=“UTF-8”
    在这里插入图片描述
  • POST请求(所有信息都在请求体中,服务器收到不会了立马解析,直到代码request.getParameter(“xxx”)执行才会解析):SpringMVC提供一个filter(要配置在所有filter之前,不然请求进不去)
	<filter>
		<filter-name>CharacterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<!-- encoding:指定解决POST请求乱码 -->
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<!-- forceEncoding:顺手解决响应乱码;response.setCharacterEncoding(this.encoding); -->
			<param-name>forceEncoding</param-name>	
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
  1. 响应乱码:
    response.setContentType(“text/html;charset=utf-8”)
2.1国际化出现乱码问题
  1. 在idea中的setting中选择
    在这里插入图片描述
  2. 在spring.xml中配置
<!--让SpringMVC管理国际化资源文件;配置一个资源文件管理器;id是必须叫messageSource  ,因为在service层spring架构中的方法设置国际化的变量名就是这个messageSource  -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <!--  basename指定基础名-->
        <property name="basename" value="i18n"></property>
    </bean>
  1. 如果还是乱码请检查此页面是否经过了spring

四.SpringMVC中AJAX与JSON

1.AJAX

说明&步骤

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
步骤:

  • 导包
    在这里插入图片描述
  • 配置(具体请回顾视频,太多类与注解的用法了)
    在方法上面使用注解@ResponseBody:将返回的数据放到响应体中,导入的jar包自动将对象转化为json

@ResponseBody:返回json数据
其中之一的用法:

@ResponseBody
    @RequestMapping("/hello02")
    public String test02(){
        return "<h1>success</h1>";
    }

在这里插入图片描述

@RequestBody:接收json数据

五.SpringMVC执行流程

  1. 所有请求,前端控制器(DispatcherServlet)收到请求,调用doDispatch进行处理
  2. 根据HandlerMapping中保存的请求映射信息找到,处理当前请求的,处理器执行链(包含拦截器)
  3. 根据当前处理器找到他的HandlerAdapter(适配器)
  4. 拦截器的preHandle先执行
  5. 适配器执行目标方法,并返回ModelAndView
    在这里插入图片描述
  6. 拦截器的postHandle执行
  7. 处理结果;(页面渲染流程)
    在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值