Spring学习笔记 之 Spring-MVC

系列文章目录 

1.spring学习笔记之spring


文章目录


Spring MVC

Spring MVC 是 Spring Framework 提供的 Web 组件,全称是 Spring Web MVC,是⽬前主流的实现 MVC 设计模式的框架,提供前端路由映射、视图解析等功能

Java Web 开发者必须要掌握的技术框架

Spring MVC 功能

MVC Controller (控制层)、 Model (模型层)、 View (视图层)
流程: Controller 接收客户端请求,调⽤相关业务层组件产出 Model ,或业务数据并返回给
Controller Controller 再结合 View 完成业务数据的视图层渲染,并将结果响应给客户端

Spring MVC 实现原

核⼼组件

  • DispatcherServlet:前置控制器,负责调度其他组件的执⾏,可以降低不同组件之间的耦合性,是整个 Spring MVC 的核⼼模块
  • Handler:处理器,完成具体的业务逻辑,相当于 Servlet
  • HandlerMappingDispatcherServlet 是通过 HandlerMapping 将请求映射到不同的 Handler
  • HandlerInterceptor:处理器拦截器,是⼀个接⼝,如果我们需要进⾏⼀些拦截处理,可以通过实现该接⼝完成
  • HandlerExecutionChain:处理器执⾏链,包括两部分内容:Handler HandlerInterceptor(系统会有⼀个默认的 HandlerInterceptor,如果需要额外拦截处理,可以 添加拦截器进⾏设置)
  • HandlerAdapter:处理器适配器,Handler 执⾏业务⽅法之前,需要进⾏⼀系列的操作包括表单的数据验证、数据类型的转换、将表单数据封装到 POJO 等,这⼀些列操作都是由
  • HandlerAdapter 完成,DispatcherServlet 通过 HandlerAdapter 执⾏不同的 Handler
  • ModelAndView:封装了模型数据和视图信息,作为 Handler 的处理结果,返回给 DispatcherServlet

组件之间运作流程


Spring MVC 具体使⽤

1.创建Maven工程,选择maven-archetype-webapp,然后在pom.xml添加以下依赖

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.3.RELEASE</version>
</dependency>

2.main文件夹下创建java文件夹和resources文件夹,resources下配置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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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.xsd
 http://www.springframework.org/schema/mvc
 http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

    <!-- 配置⾃动扫描 package路径为java下的路径-->
    <context:component-scan base-package="com.hqq"></context:component-scan>

    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 前缀 表示根目录/-->
        <property name="prefix" value="/"></property>
        <!-- 后缀 表示jsp文件-->
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>

3.在 web.xml 中配置 Spring MVC DispatcherServlet

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--指定bean配置文件-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>

  </servlet>

  <!--所有请求都拦截-->
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

4.添加controller包,添加MyHandler类

@Controller
public class MyHandler {
    @RequestMapping("/index")
    public  String index(){
        System.out.println("接收到请求");
        //返回逻辑试图
        return "index";
    }
}

5.配置Tomcat(没有的先下载),在AddConfiguration里选择tomcat,配置Deployment如下

 /:表示直接localhost:8080/index,就可以访问

如果是/test,则要localhost:8080/test/index,才可以访问

流程梳理

  1. 浏览器输入localhost:8080/index  -> DispatcherServlet 接收到 URL 请求 index,结合 @RequestMapping("/index") 注解将该请求交给index()进⾏处理
  2. 执⾏ index() 业务⽅法,控制台打印⽇志,并且返回 "index" 字符串(逻辑视图)
  3. 结合 springmvc.xml 中的视图解析器配置,"index"加上前缀/,加上后缀.jsp ->找到⽬标资源:/index.jsp,即根⽬录下的 index.jsp ⽂件,将该 JSP 资源返回给客户端完成响应


Spring MVC 常⽤注解 - @RequestMapping

Spring MVC 通过 @RequestMapping 注解将 URL 请求与业务⽅法进⾏映射,在控制器的类定义处以及⽅法定义处都可以添加 @RequestMapping ,在类定义处添加相当于多了⼀层访问路径
//----需要访问 localhost:8080/hello/index --------
@Controller
@RequestMapping("/hello")
public class HelloHandler {
     @RequestMapping("/index")
     public String index(){
     System.out.println("接收到了请求");
     //返回逻辑视图
     return "index";
     }
}
http://localhost:8080/hello/index
 
@RequestMapping 常⽤参数
  • value:指定 URL 请求的实际地址,是 @RequestMapping 的默认值
@RequestMapping(value="/index")     // = @RequestMapping("/index")  
public String index(){
     System.out.println("接收到了请求");
     //返回逻辑视图
     return "index"; 
}
  • method:指定请求的 method 类型,包括 GETPOSTPUTDELETE
@RequestMapping(value = "/index",method = RequestMethod.POST)
public String index(){
     System.out.println("接收到了请求");
     //返回逻辑视图
     return "index"; 
}
        默认访问是GET请求,所以输入localhost:8080/index出现以下错误。

         通过postman 模拟POST请求,能够被访问到:

  • params:指定 request 请求中必须包含的参数值,若不包含,⽆法调⽤该⽅法
@RequestMapping(value = "/index",params = {"id=1","name=tom"})
public String index(){
     System.out.println("接收到了请求");
     //返回逻辑视图
     return "index";
 }

        正确访问方式:localhost:8080/index?id=1&name=tom 


参数绑定 - @RequestParam

params 是对 URL 请求参数进⾏限制,不满⾜条件的 URL ⽆法访问该⽅法,需要在业务⽅法中获取 URL 的参数值
  • 1、在业务⽅法定义时声明参数列表
  • 2、给参数列表添加 @RequestParam 注解进⾏绑定
@RequestMapping(value = "/index",method = RequestMethod.POST)
public String index(@RequestParam("num") Integer id,@RequestParam("str")
String name){
     System.out.println("接收到了请求,参数是:id="+id+",name="+name);
     //返回逻辑视图
     return "index"; 
}

        正确访问URL:localhost:8080/index?num=1&str=tom

        错误访问URL  :localhost:8080/index?id=1&name=tom


RESTful ⻛格的 URL 参数获取 - @PathVariable

  • 传统的 URLlocalhost:8080/hello/index?id=1&name=tom
  • RESTful URLlocalhost:8080/hello/index/1/tom
@RequestMapping("/restful/{id}/{name}")
public String restful(@PathVariable("id") Integer id,@PathVariable("name")
String name){
     System.out.println(id+"-"+name);
     return "index"; 
}

映射 Cookie - @CookieValue

@CookieValue("JSESSIONID")能够自动获取页面的jsessionid赋给形参

@RequestMapping("/cookie")
public String getCookie(@CookieValue("JSESSIONID") String sessionId){
     System.out.println(sessionId);
     return "index";
 }

使⽤ POJO 绑定参数

POJO:一个简单的普通的Java对象,它不包含 业务逻辑或持久逻辑等
业务要求:设计一个addUser.jsp,提交一个表单,自动将输入的内容付给一个User对象
User类(POJO):
注意:主体对象User可以没有⽆参构造函数,但是级联对象Address必须有⽆参构造函数
@Data
public class User {
    private Integer id;
    private String name;
    //级联属性
    private Address address;
}

Address类(POJO):

@Data
public class Address {
    private Integer code;
    private String value;
}

addUser.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="/add" method="post">
        <table>
            <tr>
                <td>编号:</td>
                <td><input type="text" name="id"></td>
            </tr>
            <tr>
                <td>姓名:</td>
                <td><input type="text" name="name"></td>
            </tr>
            <tr>
                <td>地址编号:</td>
                <td><input type="text" name="address.code"/></td>
            </tr>
            <tr>
                <td>地址信息:</td>
                <td><input type="text" name="address.value"/></td>
            </tr>
            <tr>
                <td><input type="submit" value="提交"></td>
            </tr>
        </table>
    </form>
</body>
</html>

MyHandler

@RequestMapping(value="/add",method = RequestMethod.POST)
    public String add(User user){
        System.out.println(user);
        return "index";
    }

访问addUser.jsp页面:

提交之后,后台的User对象会获取到提交信息,根据addUser.jsp设定的属性对应赋值


 JSP ⻚⾯的转发和重定向

转发 - forward

页面跳转的时候,浏览器显示的地址不变,默认

@RequestMapping("/restful/{id}/{name}")
public String restful(@PathVariable("id") Integer id,@PathVariable("name")
String name){
     System.out.println(id+"-"+name);
     return "forward:/index.jsp";   // = return "index";
 }

重定向 - redirect

页面跳转的时候,浏览器显示的地址也跟着改变

因为不默认,所以 redirect:/   必须写完整的jsp路径

@RequestMapping("/restful/{id}/{name}")
public String restful(@PathVariable("id") Integer id,@PathVariable("name")
String name){
     System.out.println(id+"-"+name);
     return "redirect:/index.jsp"; 
}


Spring MVC 数据绑定

数据绑定:在后台业务⽅法中,直接获取前端 HTTP 请求(即在网址栏处)中的参数
  • HTTP 请求传输的参数都是 String 类型的,Handler 业务⽅法中的参数是开发者指定的数据类型,int、 Integer、Object等,因此需要进⾏数据类型的转换
  • Spring MVC HandlerAdapter 组件会在执⾏ Handler 业务⽅法之前,完成参数的绑定,开发者直接使⽤即可

基本数据类型

@RequestMapping("/baseType")
@ResponseBody        //添加这个就不会返回逻辑视图,而是将http请求参数赋给形参,后端输出
public String baseType(int id){
     return "id:"+id; 
}

正确访问:localhost:8080/baseType?id=1

错误访问:localhost:8080/baseType?id=a 或 localhost:8080/baseType

包装类

@RequestMapping("/packageType")
@ResponseBody
public String packageType(Integer id){
     return "id:"+id; 
}

此时,id可以为null,但是id不可以是浮点类型或者字符串类型

 @RequestParam 注解
@RequestMapping("/packageType")
@ResponseBody
public String packageType(@RequestParam(value = "id",required =
true,defaultValue = "0") Integer id){
     return "id:"+id; 
}
  • value = "id":将 HTTP 请求中名为 id 的参数 与 ⽅法中的形参进⾏映射
  • requiredture 表示 id 参数必填,false 表示⾮必填
  • defaultValue = "0":表示当 HTTP 请求中没有 id 参数时,形参的默认值为 0

数组

@RequestMapping("/arrayType")
@ResponseBody
public String arrayType(String[] names){
     StringBuffer stringBuffer = new StringBuffer();
     for (String str:names){
         stringBuffer.append(str).append(" ");
     }
     return "names:"+stringBuffer.toString();
}

List

Spring MVC 不⽀持 List 类型的直接转换,需要 List 的⾃定义包装类--UserList
@Data
public class UserList {
     private List<User> users; 
}
业务⽅法
@RequestMapping("/listType")
@ResponseBody
public String listType(UserList users){
     StringBuffer stringBuffer = new StringBuffer();
     for(User user:users.getUsers()){
         stringBuffer.append(user);
     }
     return "⽤户:"+stringBuffer.toString();
}
addList.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html> <head>
 <title>Title</title>
</head> <body>
 <form action="/listType" method="post">
     ⽤户1ID:<input type="text" name="users[0].id"/><br/>
     ⽤户1姓名:<input type="text" name="users[0].name"/><br/>
     ⽤户2ID:<input type="text" name="users[1].id"/><br/>
     ⽤户2姓名:<input type="text" name="users[1].name"/><br/>
     ⽤户3ID:<input type="text" name="users[2].id"/><br/>
     ⽤户3姓名:<input type="text" name="users[2].name"/><br/>
     <input type="submit" value="提交"/>
 </form>
</body>
</html>
需要注意的是 :User 类⼀定要有⽆参构造函数,否则抛出异常

JSON

引入jQuery文件,webapp下新建js文件夹,引入js文件 jquery-1.8.3.min.js,并在web.xml中配置以下信息
 <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
  </servlet-mapping>

json.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type = "text/javascript" src = "js/jquery-1.8.3.min.js"></script>
    <script type="text/javascript">
        $(function(){
            var user = {"id":1, "name":"张三"};
            $.ajax({
                url : "/jsonType",
                data : JSON.stringify(user),
                type : "POST",
                contentType:"application/json;charset=UTF-8",
                dataType:"JSON",
                success:function (data) {
                    alert(data.id)
                    alert(data.name)
                }
            })
        })
    </script>
</head>
<body>
</body>
</html>
注意
  • JSON 数据必须⽤ JSON.stringify() ⽅法转换成字符串
  • contentType:"application/json;charset=UTF-8" 不能省略
Handler方法
@RequestMapping("/jsonType")
@ResponseBody
public User jsonType(@RequestBody User user){
    System.out.println(user);
    return user;
}
  • @RequestBody 注解
读取 HTTP 请求参数,通过 Spring MVC 提供的 HttpMessageConverter 接⼝将读取的参数转为
JSON XML 格式的数据,绑定到业务⽅法的形参
  • @ResponseBody 注解
将业务⽅法返回的对象,通过 HttpMessageConverter 接⼝转为指定格式的数据, JSON XML 等,响应给客户端

FastJson

如果属性为空就不会将其转为 JSON,结合 @RequestBody 注解将 JSON 转为 Java Bean
1.pom.xml种配置依赖
    <!--FastJson-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.32</version>
    </dependency>

2.sprimvc.xml

<mvc:annotation-driven>
     <!-- 消息转换器 -->
     <mvc:message-converters>
         <bean class="org.springframework.http.converter.StringHttpMessageConverter">
             <property name="supportedMediaTypes" value="text/html;charset=UTF-8></property>
         </bean>

         <!-- fastjson -->
         <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4"></bean>
     </mvc:message-converters>
</mvc:annotation-driven>

Spring MVC 视图层解析

调⽤ Web 资源给JSP域对象传值-四大作用域
  • page
  • request
  • session
  • application
业务数据的绑定是指将业务数据绑定给 JSP 域对象,业务数据的绑定是由 ViewResolver 来完成的,开发时,我们先添加业务数据,再交给 ViewResolver 来绑定,因此学习的重点在于如何添加业务数据,Spring MVC 提供了以下⼏种⽅式来添加业务数据:
  • Map
  • Model
  • ModelAndView
  • @SessionAttribute
  • @ModelAttribute
  • Servlet API

业务数据绑定到 request 域对象

Map

Spring MVC 在调⽤业务⽅法之前会创建⼀个隐含对象作为业务数据的存储容器,设置业务⽅法的⼊参为 Map 类型, Spring MVC 会将隐含对象的引⽤传递给⼊参
1.新建ViewHandler.class
@RequestMapping("/map")
public String map(Map<String,Object> map){
     User user = new User();
     user.setId(1);
     user.setName("张三");
     map.put("user",user);
     return "show"; 
}

2.show.jsp

<%--
  Created by IntelliJ IDEA.
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!--不加上这个,会打印"${requestScope.user}"-->
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    ${requestScope.user}
</body>
</html>

3.结果

Model

Model Map 类似,业务⽅法通过⼊参来完成业务数据的绑定
@RequestMapping("/model")
public String model(Model model){
     User user = new User();
     user.setId(1);
     user.setName("张三");
     model.addAttribute("user",user);
     return "show"; 
}

ModelAndView

不同点是:返回值为ModelAndView类型,

业务⽅法中对 ModelAndView 进⾏两个操作:
  • 填充业务数据
  • 绑定视图信息
@RequestMapping("/mav")
public ModelAndView modelAndView(){
     ModelAndView modelAndView = new ModelAndView();
     User user = new User();
     user.setId(1);
     user.setName("张三");
     //填充业务数据
     modelAndView.addObject("user",user);
     //绑定视图信息
     modelAndView.setViewName("show");
     return modelAndView; 
}

HttpServletRequest

Spring MVC 可以在业务⽅法中直接获取 Servlet 原⽣ Web 资源,只需要在⽅法定义时添加
HttpServletRequest ⼊参即可,在⽅法体中直接使⽤ request 对象
在pom.xml添加servlet依赖
<!--servlet-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
    </dependency>
@RequestMapping("/request")
public String request(HttpServletRequest request){
     User user = new User();
     user.setId(1);
     user.setName("张三");
     request.setAttribute("user",user);
     return "show"; 
}

@ModelAttribute

具体使⽤步骤如下:
  • 定义⼀个⽅法,该⽅法⽤来放好要填充到业务数据中的对象
  • 给该⽅法添加 @ModelAttribute 注解
    @RequestMapping("/modelAttribute")
    public String modelAttribute(){
        return "show";
    }
    
    @ModelAttribute
    public User getUser(){
        User user = new User();
        user.setId(1);
        user.setName("张三");
        return user;
    }
解释:@ModelAttribute 注解的作⽤是,当 Handler 接收到⼀个客户端请求之后,⽆论调⽤哪个业务⽅法,都会优先调⽤被 @ModelAttribute 注解修饰的⽅法,并将其 返回值做为业务数据 ,再进⼊到业务⽅法,此时业务⽅法只需要返回视图信息即可,不需要返回业务数据,即使返回业务数据,也会被@ModelAttribute 注解修饰的⽅法返回的数据所覆盖
域对象中存值都是以 key-value 形式存储的,那么此时的 key 值是什么?默认值是业务数据对应的类的类名⾸字⺟⼩写之后的结果
另外,如果 getUser()  没有返回值,则业务数据不会传送到视图层,必须⼿动在该⽅法中填充业务数据,使⽤ Map 或者 Model 均可
@ModelAttribute
public void getUser(Model model){
     User user = new User();
     user.setId(1);
     user.setName("张三");
     model.addAttribute("user",user);
}
如果同时存在两个 @ModelAttribute 注解⽅法,则用Model装载的方法优先级更高

业务数据绑定到 session 域对象

HttpSession

@RequestMapping("/session")
public String session(HttpSession session){
     User user = new User();
     user.setId(1);
     user.setName("张三");
     session.setAttribute("user",user);
     return "show"; 
}

JSP

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!--不加上这个,会打印"${requestScope.user}"-->
<%@ page isELIgnored="false" %>

<html>
<head>
    <title>Title</title>
</head>
<body>
     <!--requestScope变为sessionScope-->
    ${sessionScope.user}
</body>
</html>

@SessionAttribute

@SessionAttribute 注解不是给⽅法添加的,⽽是给类添加
@SessionAttributes(value = "user")
public class ViewHandler{
    ....................
}
只要给类添加了 @SessionAttributes 注解之后,⽆论类中的哪个业务⽅法被访问,  request session 对象会同时存在业务数据
注:前提是 request 域中的 key 值需要和 @SessionAttributes 注解中的 value 值⼀致
@SessionAttributes 除了可以通过 key 值绑定,也可以通过业务数据的数据类型进⾏绑定:
@Controller
@SessionAttributes(types=User.class)
public class ViewHandler {
 ...
}
@SessionAttributes 可以同时绑定多个业务数据
@Controller
@SessionAttributes(types={User.class,Address.class})
public class ViewHandler {
     ...
}

只要业务方法中的request装载有User或者Address的数据,那么对应的也会给session装载上

Spring MVC⾃定义数据类型转换器

1、创建 DateConverter 类,并实现 org.springframework.core.convert.converter.Converter 接⼝, 这样它就成为了⼀个⾃定义数据类型转换器,需要指定泛型 <String,Date>,表示将 String 类型转为Date 类型
public class DateConverter implements Converter<String, Date> {
    private String pattern;

    public DateConverter(String pattern){
        this.pattern = pattern;
    }

    @Override
    public Date convert(String s) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(this.pattern);
        try {
            return simpleDateFormat.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}
2、在 springmvc.xml 中配置 conversionService bean,这个 bean
org.springframework.context.support.ConversionServiceFactoryBean 的实例化对象,同时 bean 中必须包含⼀个 converters 属性,在其中注册所有需要使⽤的⾃定义转换器
<bean id="conversionService"
          class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <bean class="com.hqq.converter.DateConverter">
                    <constructor-arg type="java.lang.String" value="yyyy-MM-dd">
                    </constructor-arg>
                </bean>
            </list>
        </property>
    </bean> 
    
    <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

3.date.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="/converter/date" method="post">
        <input type="text" name="date"/>
        <input type="submit" value="提交">
    </form>
</body>
</html>

4.Handler

@Controller
@RequestMapping("/converter")
public class ConverterHandler {

    @RequestMapping("/date")
    @ResponseBody
    public String date(Date date){
        return date.toString();
    }
}

运行步骤:

  • tomcat启动时,IOC容器会根据springmvc.xml配置的bean创建一个DateConverter对象
  • 在date.jsp页面输入日期字符串的时候,由DateConverter转为date类型,提交给Handler业务方法的入参
  • Handler将date类型数据转为String类型在视图层localhost:8080/converter/date显示日期

Spring MVCRESTful的集成

  • Resources
资源指的是⽹络中的某个具体⽂件,类型不限,可以是⽂本、图⽚、视频、⾳频、数据流等,是⽹络中 真实存在的⼀个实体。如何获取它?可以通过统⼀资源定位符找到这个实体,URI ,每个资源都有⼀个 特定的 URI ,通过 URI 就可以找到⼀个具体的资源
  • Pepresentation
资源表现层,资源的具体表现形式,例如⼀段⽂字,可以使⽤ TXT HTML XML JSON 等不同的形式来描述它
  • State Transfer
状态转化是指客户端和服务端之间的数据交互,因为 HTTP 请求不能传输数据的状态,所有的状态都保存在服务端,如果客户端希望访问服务端的数据,就需要使其发⽣状态改变,同时这种状态转化是建⽴在表现层,完成转换就表示资源的表现形式发⽣了改变

RESTful 特点:

1URL 传参更加简洁
传统形式 URL http://localhost:8080/fifindById?id=1
RESTful URL http://localhost:8080/fifindById/1
2、主要作用:完成不同终端之间的资源共享,资源传递

RESTful 具体来讲就是四种表现形式

HTTP 协议中四种请求类型( GET POST PUT DELETE )分别表示四种常规操作
  • GET ⽤来获取资源---------查
  • POST ⽤来创建资源-------增
  • PUT ⽤来修改资源---------改
  • DELETE ⽤来删除资源---删

两个终端要完成数据交互,基于 RESTful 的⽅式,增删改查操作分别需要使⽤不同的 HTTP 请求类型来访问

传统的 Web 开发中,from 只⽀持 GET POST,不⽀持 DELETE PUT,如何解决?通过添加HiddenHttpMethodFilter 过滤器,可以将 POST 请求转为 PUT 或者 DELETE

HiddenHttpMethodFilter 的实现原理

HiddenHttpMethodFilter 检测请求参数重是否包含 _method 参数,如果包含则取出它的值,并且判断请求类型之后完成请求类型的转换,然后继续传递

实现

1.在form表单中添加隐藏于标签,name为_method,value为DELETE/PUT

<html>
<head><title>Title</title></head>
<body>
<form action="/rest/update" method="post"> <!--本来请求是POST-->
    <%--用_method,转为PUT请求--%>
    <input type="hidden" name="_method" value="PUT"/>
    <input type="submit" value="提交"/>
</form>
</body>
</html>
2web.xml 中配置 HiddenHttpMethodFilter
<!-- HiddenHttpMethodFilter -->
<filter>
     <filter-name>HiddenHttpMethodFilter</filter-name>
     <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filterclass>
</filter> 

<filter-mapping>
     <filter-name>HiddenHttpMethodFilter</filter-name>
     <url-pattern>/*</url-pattern>
</filter-mapping>

3.Handler

@PutMapping("/update")
@ResponseBody
public String update(HttpServletResponse response){
        //添加可以避免输出中文乱码
     response.setCharacterEncoding("UTF-8");
     return "已接收到PUT请求"; 
}
小demo需求分析
  • 添加课程,成功则返回全部课程信息
  • 查询课程,通过 id 查询对应课程信息
  • 修改课程,成功则返回修改之后的全部课程信息
  • 删除课程,成功则返回删除之后的全部课程信息
代码实现
1 JSP
添加课程: addCourse.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="/course/add" method="post">
        <table>
            <tr>
                <td>课程编号:</td>
                <td><input type="text" name="id"></td>
            </tr>
            <tr>
                <td>课程名称:</td>
                <td><input type="text" name="name"></td>
            </tr>
            <tr>
                <td>课程价格:</td>
                <td><input type="text" name="price"></td>
            </tr>
            <tr>
                <td><input type="submit" value="提交"></td>
                <td><input type="reset" value="重置"></td>
            </tr>
        </table>
    </form>
</body>
</html>
修改课程: edit.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html> <head>
    <title>Title</title>
</head> <body>
<form action="/course/update" method="post">
    <input type="hidden" name="_method" value="PUT"/>
    <table>
        <tr>
            <td>编号:</td>
            <td>
                <input type="text" name="id" readonly value="${courser.id}"/>
            </td>
        </tr>
        <tr>
            <td>名称:</td>
            <td>
                <input type="text" name="name" value="${courser.name}"/>
            </td>
        </tr>
        <tr>
            <td>价格:</td>
            <td>
                <input type="text" name="price" value="${courser.price}"/>
            </td>
        </tr>
        <tr>
            <td>
                <input type="submit" value="修改"/>
            </td>
        </tr>
    </table>
</form>
</body>
</html>
课程展示: index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page isELIgnored="false" %>
<html>
<body>
    <h2>Hello World!</h2>
    <table>
        <tr>
            <th>编号</th>
            <th>名称</th>
            <th>价格</th>
            <th>操作</th>
        </tr>
        <!--modelAndView对象装载的key叫list-->
        <c:forEach items="${list}" var="course">
            <tr>
                <td>${course.id}</td>
                <td>${course.name}</td>
                <td>${course.price}</td>
                <td>
                    <form action="/course/deleteById/${course.id}" method="post">
                        <input type="hidden" name="_method" value="DELETE">
                        <input type="submit" value="删除">
                    </form>
                    <a href="/course/findById/${course.id}">修改</a>
                </td>
            </tr>
        </c:forEach>
        <tr>
            <td>
                <form action="/addCource.jsp" method="post">
                    <input type="submit" value="添加">
                </form>
            </td>
        </tr>
    </table>
</body>
</html>

注:使用c:forEach要添加jstl包,在pom.xml添加以下依赖

<!--JSTL-->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

乱码解决方法:在springmvc.xml中把中文乱码过滤器放在最上

<!--SpringMVC 中文乱码-->
  <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>
  </filter>

  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!-- 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>

2.实体类Course 

@Repository
public class CourseRepository {
    private Map<Integer, Course> courseMap;

    public CourseRepository(){
        courseMap = new HashMap<>();
        courseMap.put(1,new Course(1,"Java基础",35.0));
        courseMap.put(2,new Course(2,"Java高级",45.0));
        courseMap.put(3,new Course(3,"企业级框架",55.0));
    }

    public Collection<Course> findAll(){
        return courseMap.values();
    }

    public Course findById(Integer id){
        return courseMap.get(id);
    }

    public void saveOrUpdate(Course course){
        courseMap.put(course.getId(),course);
    }

    public void deleteById(Integer id){
        courseMap.remove(id);
    }
3 CourseRepository(代替数据库)
@Repository
public class CourseRepository {
    private Map<Integer, Course> courseMap;

    public CourseRepository(){
        courseMap = new HashMap<>();
        courseMap.put(1,new Course(1,"Java基础",35.0));
        courseMap.put(2,new Course(2,"Java高级",45.0));
        courseMap.put(3,new Course(3,"企业级框架",55.0));
    }

    public Collection<Course> findAll(){
        return courseMap.values();
    }

    public Course findById(Integer id){
        return courseMap.get(id);
    }

    public void saveOrUpdate(Course course){
        courseMap.put(course.getId(),course);
    }

    public void deleteById(Integer id){
        courseMap.remove(id);
    }
}
4 CourseController
@Controller
@RequestMapping("/course")
public class CourseController {

    @Autowired
    private CourseRepository courseRepository;

    @PostMapping("/add")
    public String add(Course course){
        courseRepository.saveOrUpdate(course);
        return "redirect:/course/findAll";
    }

    @GetMapping("/findAll")
    public ModelAndView findAll(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("index");
        modelAndView.addObject("list",courseRepository.findAll());
        return modelAndView;
    }

    @DeleteMapping("/deleteById/{id}")
    public String deleteById(@PathVariable("id") Integer id){
        courseRepository.deleteById(id);
        return "redirect:/course/findAll";
    }

    @GetMapping("findById/{id}")
    public ModelAndView findById(@PathVariable("id") Integer id){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("edit");
        modelAndView.addObject("courser",courseRepository.findById(id));
        return modelAndView;
    }

    @PutMapping("/update")
    public String update(Course course){
        courseRepository.saveOrUpdate(course);
        return "redirect:/course/findAll";
    }

}

Spring MVC实现⽂件的上传下载

单⽂件上传

1. 底层使⽤的是 Apache fifileupload 组件完成上传功能, Spring MVC 只是对其进⾏了封装,简化开发,pom.xml添加依赖
    <!--文件上传-->
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.5</version>
    </dependency>

    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.4</version>
    </dependency>

2. JSP ⻚⾯

  • input type 设置为 fifile
  • form 表单的 method 设置为 post
  • form 表单的 enctype 设置为 multipart/form-data

demo:做一个上传图片,然后展示此图片的网页

upload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="/file/upload" method="post" enctype="multipart/form-data">
        <input type="file" name="img"/>
        <input type="submit" value="提交">
    </form>
    <img src="${src}">
</body>
</html>

uploadHandler

@Controller
@RequestMapping("/file")
public class upLoadHandler {

    @PostMapping("/upload")
    public String upload(@RequestParam("img")MultipartFile img, HttpServletRequest request){
        if(img.getSize()>0){
            //1.path = apache-tomcat-9.0.63/webapps/ROOT/file    2.getRealPath("file")表示/ROOT/下的file文件夹
            String path = request.getSession().getServletContext().getRealPath("file");
            String fileName = img.getOriginalFilename();
            //将path下的名字为fileName的文件变为对象
            File file = new File(path,fileName);
            try {
                //上传文件到服务器
                img.transferTo(file);
                request.setAttribute("src","/file/"+fileName);  //”/file/“ = ”ROOT/file/"
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "upload";
    }
}

配置图片静态资源访问-web.xml

 <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.jpg</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.png</url-pattern>
  </servlet-mapping>

配置multipartResolverbean-springmvc.xml

<bean id="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

多⽂件上传

uploads.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="/file/uploads" method="post" enctype="multipart/form-data">
        file1:<input type="file" name="imgs"/><br>
        file2:<input type="file" name="imgs"/><br>
        file3:<input type="file" name="imgs"/><br>
        <input type="submit" value="提交">
    </form>

    <c:forEach items="${list}" var="path">
        <img src="${path}" width="300px">
    </c:forEach>
</body>
</html>

Handler

@PostMapping("uploads")
    public String uploads(@RequestParam("imgs")MultipartFile[] imgs,HttpServletRequest request){
        //存放文件路径
        List<String> pathList = new ArrayList<>();

        for (MultipartFile img:imgs) {
           if(img.getSize()>0){
               String path =request.getSession().getServletContext().getRealPath("file");
               String fileName = img.getOriginalFilename();
               File file = new File(path,fileName);
               try {
                   img.transferTo(file);
                   pathList.add("/file/"+fileName);
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
        }
        //request保存文件路径,直接src指定路径,显示图片
        request.setAttribute("list",pathList);
        return "uploads";

⽂件下载

1JSP ⻚⾯中添加超链接,进⾏下载(前提已经img.transferTo(file)上传到服务器)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html> <head>
 <title>Title</title>
</head> <body>
 <a href="/file/download?fileName=1.png">1.png</a><br/>
 <a href="/file/download?fileName=2.png">2.png</a><br/>
 <a href="/file/download?fileName=3.png">3.png</a>
</body>
</html>

2.Handler

    @GetMapping("/download")
    public void download(String fileName, HttpServletRequest request, HttpServletResponse response){
        if (fileName!=null){
            String path =request.getSession().getServletContext().getRealPath("file");
            File file = new File(path,fileName);
            OutputStream outputStream =null;
            if (file.exists()){
                //设置下载文件
                response.setContentType("application/force-download");
                //设置文件名
                response.setHeader("Content-Disposition","attachment;filename="+fileName);
                try {
                    outputStream = response.getOutputStream();
                    outputStream.write(FileUtils.readFileToByteArray(file));
                    outputStream.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    if(outputStream!=null){
                        try{
                            //关流
                            outputStream.close();
                        }catch (IOException e){
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

Spring MVC 数据校验

数据校验是每个项⽬中必不可少的模块, Spring MVC 提供了两种数据校验的组件:
  • 基于 Validator 接⼝进⾏校验
  • 使⽤ Annotation JSR-303 标准校验
使⽤基于 Validator 接⼝进⾏校验会复杂⼀些,具体的数据校验的规则需要开发者⼿动设置。⽽使⽤Annotation JSR-303 标准会相对简单⼀些,开发者不需要编写校验规则,直接通过注解的形式给每⼀条数据添加验证规则,具体操作是直接在实体类的属性上添加对应的校验注解即可

基于 Validator 接⼝

1.创建Student实体类

@Data
public class Student {
     private String name;
     private String password;
 }
2、⾃定义数据校验器 StudentValidation,实现 Validator 接⼝
public class StudentValidation implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
        return clazz.equals(Student.class);
    }

    @Override
    public void validate(Object target, Errors errors) {
        //rejectIfEmpty(error表示会报错,”name“表示name属性,null表示如果值是null的时候,默认报错信息是”姓名不能为空“)
        ValidationUtils.rejectIfEmpty(errors,"name",null,"(提示:姓名不能为空)");
        ValidationUtils.rejectIfEmpty(errors,"password",null,"(提示:密码不能为空)");
    }
}

3.login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!--引入表单标签库-->
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
    <title>学生登陆</title>
</head>
<body>
    <h1>登陆系统</h1>
    <!--modelAttribute指定了在Handler业务方法中添加了需要校验的对象-->
    <form:form modelAttribute="student" action="/validate/login" method="post">
        <tr>学生姓名:<form:input path="name"></form:input><form:errors path="name"></form:errors></tr>
        学生密码:<form:input path="password"></form:input><form:errors path="password"></form:errors>
        <tr><input type="submit" value="提交"></tr>
    </form:form>
</body>
</html>

4、控制层业务⽅法

必须通过/validate/login 去访问,因为login()方法会通过model传一个student对象才能启动校验规则,直接访问login.jsp会报错

@Controller
@RequestMapping("/validate")
public class ValidateHandler {

    //给JSP表单绑定模型对象,绑定才能启用校验
    @GetMapping("/login")
    public String login(Model model){
        model.addAttribute(new Student());
        return "login";
    }

    //数据校验
    @PostMapping("login")
    public String login(@Validated Student student, BindingResult bindingResult){
        if (bindingResult.hasErrors()){
            return "login";
        }
        return "success";
    }
}

5springmvc.xml 配置 validator

<bean id="studentValidator" class="com.hqq.validation.StudentValidation"></bean>
<!--指定bean id-->
<mvc:annotation-driven validator="studentValidator"></mvc:annotation-driven>
 

6.结果:

 Annotation JSR-303 标准

Hibernater Validator ,通过注解完成校验规则的绑定
  • @Null 只能为 null
  • @NotNull 不能为 null
  • @Size 设置数据⻓度
  • @NotEmpty 不能为空
  • String str = null;
  • String str = "";

1.在pom.xml上添加依赖

    <!--JSR 303 JSR是Java Specification Requests的缩写,意思是Java 规范提案-->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>5.3.6.Final</version>
    </dependency>
    <dependency>
      <groupId>javax.validation</groupId>
      <artifactId>validation-api</artifactId>
      <version>2.0.1.Final</version>
    </dependency>
    <dependency>
      <groupId>org.jboss.logging</groupId>
      <artifactId>jboss-logging</artifactId>
      <version>3.4.1.Final</version>
    </dependency>

    <!-- JDK9以上 另外要添加以下依赖 -->
    <dependency>
         <groupId>javax.xml.bind</groupId>
         <artifactId>jaxb-api</artifactId>
         <version>2.3.1</version>
    </dependency>
    <dependency>
         <groupId>com.sun.xml.bind</groupId>
         <artifactId>jaxb-impl</artifactId>
         <version>2.3.0</version>
    </dependency>
    <dependency>
         <groupId>com.sun.xml.bind</groupId>
         <artifactId>jaxb-core</artifactId>
         <version>2.3.0</version>
    </dependency>
    <dependency>
         <groupId>javax.activation</groupId>
         <artifactId>activation</artifactId>
         <version>1.1.1</version>
    </dependency>

2.创建Account实体类,并用注解的方式指定校验规则

import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

/**
 * @Author 苦恼的java小宝
 * @Date 2022/6/13 18:00
 * @ClassName: Account
 * @Version 1.0
 */
@Data
public class Account {
    @NotEmpty(message = "用户名不能为空")
    private String username;

    @Size(min = 6,max = 20,message = "密码长度为6-20位")
    private String password;

    @Email(regexp = "\"^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\\\\\\\\\\\\\\\.[a-zA-Z0-9-\n" +
            "]+)*\\\\\\\\\\\\\\\\.[a-zA-Z0-9]{2,6}$",message ="请输入正确的邮箱" )
    private String email;

    @Pattern(regexp = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\\\\\\\\\\\\\\\d{8}$",message = "请输入正确的手机号")
    private String phone;
}

3.Handler

@GetMapping("/register")
public String register(Model model){
     model.addAttribute(new Account());
     return "register"; 
}

@PostMapping("/register")
public String register(@Valid Account account,BindingResult bindingResult){
     if(bindingResult.hasErrors()){
         return "regiser";
     }
     return "success"; 
}

4、register.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>⽤户注册</h1>
    <form:form modelAttribute="account" action="/validate/register" method="post">
    ⽤户名:<form:input path="username"></form:input><form:errors path="username"></form:errors><br/>
    密码:<form:input path="password"></form:input><form:errors path="password"></form:errors><br/>
    邮箱:<form:input path="email"></form:input><form:errors path="email"></form:errors><br/>
    电话:<form:input path="phone"></form:input><form:errors path="phone"></form:errors><br/>
    <input type="submit" value="提交"/>
    </form:form>
</body>
</html>

Spring MVC表单标签库

demo:通过jsp修改student的信息

1.Student实体类

@Data
public class Student {
     private Integer id;
     private String name;
     private Integer age;
     private String gender; }

2.Handler

@Controller
@RequestMapping("/student")
public class StudentHandler {

    @RequestMapping("/get")
    public String get(Model model){
        Student student = new Student();
        student.setId(1);
        student.setName("张三");
        student.setAge(22);
        student.setGender("男");
        model.addAttribute("student",student);
        return "student";
    }
}

3.student.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>修改学⽣信息</h1>
    <%--不用表单标签库的情况--%>
    <form action="" method="post">
        学⽣编号:<input type="text" name="id" value="${student.id}" readonly/><br/>
        学⽣姓名:<input type="text" name="name" value="${student.name}"/><br/>
        学⽣年龄:<input type="text" name="age" value="${student.age}"/><br/>
        学⽣性别:<input type="text" name="gender" value="${student.gender}"/><br/>
        <input type="submit" value="提交"/>
    </form>

    <%--使用表单标签库的情况--%>
    <%--功能一样,代码简单--%>
    <form:form modelAttribute="student" action="/student/update" method="post">
        学⽣编号:<form:input path="id"></form:input><br/>
        学⽣姓名:<form:input path="name"></form:input><br/>
        学⽣年龄:<form:input path="age"></form:input><br/>
        学⽣性别:<form:input path="gender"></form:input><br/>
        <input type="submit" value="提交"/>
    </form:form>
</body>
</html>

常⽤标签

1form 标签
<!--渲染的是 HTML 中的 <form></form> ,通过 modelAttribute 属性绑定具体的业务数据-->
<form:form modelAttribute="student" method="post"></form:form>

2input 标签

渲染的是 HTML 中的 <input type="text"/> from 标签绑定的是业务数据,input 标签绑定的是业 务数据中的属性值,通过 path 与业务数据的属性名对应,并⽀持级联

<form:input path="name"></form:input>

3password 标签

渲染的是 HTML 中的 <input type="password"/> ,通过 path 与业务数据的属性名对应
password跟input的区别是:password 标签的值不会在⻚⾯显示
<form:password path="password"></form:password>

4checkbox 标签

渲染的是 HTML 中的 <input type="checkbox"/> ,通过 path 与业务数据的属性名对应,可以绑定 boolean、数组和集合

<form:checkbox path="hobby" value="读书"></form:checkbox>
如果绑定 boolean 类型的变量,该变量值为 true ,则表示选中, false 表示不选中
5checkboxs 标签
渲染的是 HTML 中的⼀组 <input type="checkbox"/> ,这⾥需要结合 items path 两个属性来使
⽤, items 绑定被遍历的集合或数组, path 绑定选中的集合或数组, items 是全部选型, path 为默认 选中的选型
<form:checkboxs items="${student.hobby}" path="selectHobby"></form:checkboxs>
6radiobutton 标签
渲染的是 HTML 中的⼀个 <input type="radio"/> ,绑定的数据与标签的 value 值相等为选中状
态,否则为不选中状
student.setRadioId(1);
<form:radiobutton path="radioId" value="0"></form:radiobutton>男
<form:radiobutton path="radioId" value="1"></form:radiobutton>⼥

Spring MVC国际化

国际化是指同⼀个应⽤程序在不同语⾔设置的浏览器中,⾃动显示不同的语⾔, Spring MVC 对国际化操作做了很好的集成,只需要简单配置即可实现国际化
1.配置springmvc.xml
<!-- 国际化资源⽂件 -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSour
ce">

 <!-- 多语⾔配置⽂件放在根路径,以 language 开头 -->
 <property name="basename" value="classpath:language"></property>
 <property name="useCodeAsDefaultMessage" value="true"></property>
</bean>

<!-- 拦截器 -->
<mvc:interceptors>
 <bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
 <property name="paramName" value="lang"></property>
 </bean>
</mvc:interceptors>

<!-- 配置 SessionLocaleResolver,动态获取 Locale 对象,存⼊ Session -->
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>
2、创建国际化资源⽂件 language_en_US.propertieslanguage_zh_CN.properties,分别存储英⽂和中⽂资源
language.cn = \u4E2D\u6587
language.en = English
info = login
username = username
password = password
repassword = repassword
tel = tel
email = email
submit = submit
reset = reset
language.cn = \u4E2D\u6587
language.en = English
info = \u767B\u9646
username = \u7528\u6237\u540D
password = \u5BC6\u7801
repassword = \u786E\u8BA4\u5BC6\u7801
tel = \u7535\u8BDD
email = \u7535\u5B50\u90AE\u7BB1
submit = \u63D0\u4EA4
reset = \u91CD\u7F6E
3Handler
@Controller
@RequestMapping("/inter")
public class InterHandler {
     @GetMapping("/index")
     public String index(){
         return "inter";
     }
}
4、inter.JSP
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<html> 
<head>
     <title>Title</title>
</head> 
<body>
     <a href="index?lang=en_US">English</a>
     <a href="index?lang=zh_CN">中⽂</a>
     <h1><spring:message code="info"></spring:message></h1>
     <form>
         <spring:message code="username"/>:<input type="text"/><br/>
         <spring:message code="password"/>:<input type="password"/><br/>
         <spring:message code="repassword"/>:<input type="password"/><br/>
         <spring:message code="tel"/>:<input type="text"/><br/>
         <spring:message code="email"/>:<input type="text"/><br/>
         <input type="submit" value="<spring:message code="submit"/> "/>
         <input type="reset" value="<spring:message code="reset"/> "/>
     </form>
</body>
</html>

5、结果

总结

开始myBatis

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值