• Spring MVC框架


    Spring MVC

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

    Spring MVC功能

    MVC:Controller(控制层),Model(模型层),View(视图层)
    流程:Controller接收客户端请求,调用相关业务层组件产出Model,或业务数据并返回给Controller,Controller再结合View完成业务数据的视图层渲染,并将结果响应给客户端。
    Spring MVC对这套MVC流程进行封装,帮助开发者屏蔽底层代码,并且开放相关接口供开发者调用,让MVC开发变得更加简单方便。

    Spring MVC实现原理

    核心组件

    组件作用
    DispatcherServlet前置控制器,负责调度其他组件的执行,可以降低不同组件之间的耦合性,是整个Spring MVC的核心模块
    Handler处理器,完成具体的业务逻辑,相当于Servlet
    HandlerMappingDispatcherServlet是通过HandlerMapping将请求映射到不同的Handler
    HandlerInterceptor处理器拦截器,是一个接口,如果需要进行一些拦截处理,可以通过该接口完成
    HandlerExecutionChain处理器执行链,包括两部分内容:Handler和HandlerInterceptor(系统会有一个默认的HandlerInterceptor,如果需要额外拦截处理,可以添加拦截器进行设置)
    HandlerAdapter处理器适配器,Handler执行业务方法之前,需要进行一系列的操作包括表单的数据验证、数据类型的转换、将表单封装到POJO等
    ModelAndView封装了模型数据和视图信息,作为Handler的处理结果,返回给DispatcherServlet
    ViewResolver视图解析器,DispatcherServlet通过它将逻辑视图解析为物理视图,最终将渲染的结果响应给客户端

    工作流程

    1. 客户端请求被DispatcherServlet接收
    2. 根据HandlerMapping映射到Handler
    3. 生成Handler和HandlerInterceptor
    4. Handler和HandlerInterceptor以HandlerExecutionChain的形式一并返回给DispatcherServlet
    5. DispatcherServlet通过HandlerAdapter调用Handler的方法完成业务逻辑处理
    6. 返回一个ModelAndView对象给DispatcherServlet
    7. DispatcherServlet将获取的ModelAndView视图解析器,将逻辑视图解析成物理视图
    8. ViewResolver返回一个View给DispatcherServlet
    9. DispatcherServlet根据View进行视图渲染(将模型数据填充到视图中)
    10. DispatcherServlet将渲染之后的视图响应给客户端

    一个简单的例子:

    添加一个Maven工程,导入pom依赖

    
        
            org.springframework
            spring-webmvc
            {版本号}
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在web.xml中配置SpringMVC的DispatcherServlet

        
            springmvc
            org.springframework.web.servlet.DispatcherServlet
            
                contextConfigLocation
                classpath:springmvc.xml
            
        
        
            springmvc
            /
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    配置springmvc.xml

    
    
        
        
        
        
            
            
            
            
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    创建Handler

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class HelloHandler {
        @RequestMapping("/index")
        public String index(){
            System.out.println("接收到了请求");
            //返回逻辑视图
            return "index";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    流程梳理

    1. DispatcherServlet接收到URL请求index,结合@RequestMapping(“/index”)注解将该请求交给index业务方法进行处理
    2. 执行index业务方法,控制台打印日志,并返回"index"字符串(逻辑视图)
    3. 结合springmvc.xml中的视图解析器配置,找到目标资源:index.jsp,即根目录下的index.jsp文件将该JSP资源返回给客户端完成响应
      Spring MVC环境搭建成功

    Spring MVC常用注解

    @RequestMapping
    Spring MVC通过@RequestMapping注解将URL请求与业务方法进行映射,在控制器的类定义处以及方法定义处都可以添加@RequestMapping,在类定义处添加相当于多了一层访问路径。
    如上例,在类定义处加上该注解有

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    @RequestMapping("/hello")
    public class HelloHandler {
        @RequestMapping("/index")
        public String index(){
            System.out.println("接收到了请求");
            //返回逻辑视图
            return "index";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    则访问地址变为:http://localhost:8080/hello/index

    @RequestMapping常用参数

    参数用法
    value指定URL请求的实际地址,是@RequestMapptin的默认值,只有一个参数时可以省略,两个或以上参数时必须写
    method指定请求的method类型,包括GET、POST、PUT、DELETE等
    params指定request请求中必须包含的参数值,若不包含,无法调用该方法
    params同时指定多个参数则写成params={"key1=value1","key2=value2"}的形式
    该形式代码表名请求中必须包含key1和key2两个参数,并且值必须为其对应的值,否则抛出400错误
    参数绑定

    params是对URL请求参数进行限制,不满足条件的URL无法访问该方法,需要在业务方法中获取URL的参数值

    1. 在业务方法定义时声明参数列表
    2. 给参数列表添加@RequestParam注解进行绑定

    例:将controller改为post方法,且传递参数num和str

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    
    @Controller
    public class HelloHandler {
        @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";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    Spring MVC也支持RESTful风格的URL参数获取

    传统的URL:localhost:8080/index?id=1&name=tom
    RESTful URL:localhost:8080/hello/index/1/tom

    修改controller

        @RequestMapping("/restful/{id}/{name}")
        public String restful(@PathVariable("id") Integer id,@PathVariable("name") String name){
            System.out.println(id+"-"+name);
            return "index";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    将参数列表的注解改为@PathVariable即可实现。

    映射Cookie

        @RequestMapping("/cookie")
        public String getCookie(@RequestParam(required = false)@CookieValue("JSESSIONID") String sessionId){
            System.out.println(sessionId);
            return "index";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    使用POJO绑定参数

    Spring MVC会根据请求参数名和POJO属性名进行匹配,自动为该对象填充属性值,并支持级联
    创建实体类User

    import lombok.Data;
    
    @Data
    public class User {
        private Integer id;
        private String name;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    新建一个addUser.jsp文件

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    
        Title
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    在controller类中添加

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

    即可实现数值接收

    如果出现中文乱码问题可以通过配置过滤器来解决,在web.xml中添加:

      
        encodingFilter
        org.springframework.web.filter.CharacterEncodingFilter
        
          encoding
          UTF-8
        
      
      
        encodingFilter
        /*
      
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    再加一套User里面的实体类Address,User变为

    import lombok.Data;
    
    @Data
    public class User {
        private Integer id;
        private String name;
        private Address address;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    Address类

    import lombok.Data;
    
    @Data
    public class Address {
        private Integer code;
        private String value;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    addUser.jsp添加地址信息

    
    
        Title
    
    
    
    编号:
    姓名
    地址编号:
    地址信息:
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    框架可以根据变量名找到实体类中的变量自动进行绑定

    主体对象可以没有无参构造函数,但是级联对象必须有无参构造函数

    JSP页面的转发和重定向

    Spring MVC默认以转发的形式响应JSP,可以手动进行修改。

    以上述RESTful例为例,重定向访问

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

    注:设置重定向的时候不能写逻辑视图,必须写明资源的物理路径,如"redirect:/index.jsp"

    转发的写法:

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

    等同于

        @RequestMapping("/restful/{id}/{name}")
        public String restful(@PathVariable("id") Integer id,@PathVariable("name") String name){
            System.out.println(id+"-"+name);
            return "index";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Spring MVC数据绑定

    数据绑定:在后台业务方法中,直接获取前端HTTP请求中的参数
    HTTP请求传输的参数都是String类型的,Handler业务方法中参数是开发者指定的数据类型,int、Integer、Object,因此需要进行数据类型的转换。

    Spring MVC的Handler Adapter组件会在执行Handler业务方法之前,完成参数的绑定,开发者可以直接使用。

    • 基本数据类型

    例:在Controller添加

        @RequestMapping("/baseType")
        @ResponseBody
        public String baseType(int id)
        {
            return "id:"+id;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    @ResponseBody会直接返回id的字符串。

    客户端HTTP请求中必须包含id参数,否则抛出500异常,因为id不能为null。同时id的值必须为数值且必须为整数,否则抛出400异常。

    • 包装类
        @RequestMapping("/packageType")
        @ResponseBody
        public String packageType(Integer id){
            return "id:"+id;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如果HTTP请求中没有包含id参数,不会报错,id的值就是null,会直接返回id:null给客户端。但是如果id=a或者id=1.5同样会抛出400异常,因为数据类型无法匹配。

    可以给参数列表添加@RequestParam注解,可以对参数进行相关设置

        @RequestMapping("/packageType")
        @ResponseBody
        public String packageType(@RequestParam(value = "id",required = true,defaultValue = "0") Integer id){
            return "id:"+id;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    value="id"将HTTP请求中名为id的参数与Handler业务方法中的形参进行映射
    requiredtrue表示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();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • POJO
      已在上例中体现加入@ResponseBody时返回值有乱码

    为了使返回值不出现乱码,所以在springmvc.xml中加入

    
            
            
                
                    
                
            
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • List

    Spring MVC不支持List类型的直接转换,需要包装成Object。
    List自定义包装类

    类UserList

    import lombok.Data;
    
    import java.util.List;
    @Data
    public class UserList {
        private List users;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    addList.jsp

    
    
        Title
    
    
        
    用户1ID:
    用户1姓名:
    用户2ID:
    用户2姓名:
    用户3ID:
    用户3姓名:
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    Controller类

        @RequestMapping(value = "/listType",method = RequestMethod.POST)
        @ResponseBody
        public String listType(UserList users){
            StringBuffer stringBuffer=new StringBuffer();
            for(User user:users.getUsers())
            {
                stringBuffer.append(user);
            }
            return "users:"+users.toString();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    User类与前例一致,需要注意的是User类一定要有无参构造器,否则报错

    • Json

    在pom.xml中添加依赖

        
          com.alibaba
          fastjson
          1.2.79
        
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在springmvc.xml中配置

        
            
                
                
            
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在web.xml文件中添加读取js文件的标签

      
        default
        *.js
      
    
    • 1
    • 2
    • 3
    • 4

    导入jQuery.min.js文件
    创建json.jsp

    
    
        Title
        
        
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    则数据从页面传入后端再由后端返回给页面

    • Json数据必须用JSON.stringify()方法转换成字符串
    • contentType:"application/json;charset=UTF-8"不能省略

    业务方法

        @RequestMapping("/jsonType")
        @ResponseBody
        public User jsonType(@RequestBody User user){
           user.setId(2);
            return user;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    @RequestBody注解
    读取HTTP请求参数,通过SpringMVC提供的HttpMessageConverter接口读取的参数转为JSON、XML格式的数据,绑定到业务方法的形参。

    @ResponseBody注解
    将业务方法返回的对象,通过HttpMessageConverter接口转为指定格式的数据,JSON、XML等,响应给客户端。
    需要使用组件结合@RequestBody注解将JSON转换为Java Bean,这里使用FastJson,其优势是如果属性为空就不会将其转为JSON

    Spring MVC视图层解析

    调用Web资源给域对象传值

    page

    request

    session

    application

    业务数据的绑定是指将业务数据绑定给JSP域对象,业务数据的绑定是由ViewResolver来完成,开发时,先添加业务数据,再交给ViewResolver来绑定。Spring MVC提供了以下几种方式来添加业务数据:

    • Map
    • Model
    • ModelAndView
    • @SessionAttribute
    • @ModelAttribute
    • Servlet API
    业务数据绑定到request域对象
    Map

    Spring MVC在调用业务方法之前会创建一个隐含对象作为业务数据的存储容器,设置业务方法的入参为Map类型,Spring MVC会将隐含对象的引用传递给入参。

    创建一个Controller类ViewHandler

    import com.test.entity.User;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import java.util.Map;
    
    @Controller
    @RequestMapping("/view")
    public class ViewHandler {
        @RequestMapping("/map")
        public String map(Map map){
            User user=new User();
            user.setId(1);
            user.setName("张三");
            map.put("user",user);
            return "show";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    创建一个show.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ page isELIgnored="false"%>
    
    
        Title
    
    
    ${requestScope.user}
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    Model

    Model与Map类似,业务方法通过入参来完成业务数据的绑定

    Controller类写入

        @RequestMapping("/model")
        public String model(Model model)
        {
            User user=new User();
            user.setId(1);
            user.setName("张三");
            model.addAttribute("user",user);
            return "show";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    ModelAndView

    与Map或者Model不同的是,ModelAndView不但包含业务数据,同时也封装了视图信息,如果使用ModelAndView来处理业务数据,业务方法的返回值必须是ModelAndView对象

    业务方法中对ModelAndView进行两个操作:

    • 填充业务数据
    • 绑定试图信息

    方法一

     public ModelAndView modelAndView1()
        {
            ModelAndView modelAndView=new ModelAndView();
            User user=new User();
            user.setId(1);
            user.setName("张三");
            //填充业务数据
            modelAndView.addObject("user",user);
            //绑定视图信息
            modelAndView.setViewName("show");
            return modelAndView;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    方法二

    @RequestMapping("/mav2")
        public ModelAndView modelAndView2(){
            ModelAndView modelAndView=new ModelAndView();
            User user=new User();
            user.setId(1);
            user.setName("张三");
            modelAndView.addObject("user",user);
            View view=new InternalResourceView("/show.jsp");
            modelAndView.setView(view);
            return modelAndView;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    方法三

     @RequestMapping("/mav3")
        public ModelAndView modelAndView3()
        {
            ModelAndView modelAndView=new ModelAndView("show");
            User user=new User();
            user.setId(1);
            user.setName("张三");
            modelAndView.addObject("user",user);
            return modelAndView;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    方法四

     @RequestMapping("/mav4")
        public ModelAndView modelAndView4()
        {
            View view=new InternalResourceView("/show.jsp");
            ModelAndView modelAndView=new ModelAndView(view);
            User user=new User();
            user.setId(1);
            user.setName("张三");
            modelAndView.addObject("user",user);
            return modelAndView;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    方法五

    @RequestMapping("/mav5")
        public ModelAndView modelAndView5(){
            Map map=new HashMap<>();
            User user=new User();
            user.setId(1);
            user.setName("张三");
            map.put("user",user);
            ModelAndView modelAndView=new ModelAndView("show",map);
            return modelAndView;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    方法六

     @RequestMapping("/mav6")
        public ModelAndView modelAndView6()
        {
            Map map=new HashMap<>();
            User user=new User();
            user.setId(1);
            user.setName("张三");
            map.put("user",user);
            View view=new InternalResourceView("/show.jsp");
            ModelAndView modelAndView=new ModelAndView(view,map);
            return modelAndView;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    方法七

     @RequestMapping("/mav7")
        public ModelAndView modelAndView7(){
            User user=new User();
            user.setId(1);
            user.setName("张三");
            ModelAndView modelAndView=new ModelAndView("show","user",user);
            return modelAndView;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    方法八

        @RequestMapping("/mav8")
        public ModelAndView modelAndView8(){
            User user=new User();
            user.setId(1);
            user.setName("张三");
            View view=new InternalResourceView("/show.jsp");
            ModelAndView modelAndView=new ModelAndView(view,"user",user);
            return modelAndView;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    HttpServletRequest

    Spring MVC可以在业务方法中直接获取Servlet原生Web资源,只需要在方法定义时添加HttpServletRequest入参即可,在方法体中直接使用request对象

    添加pom.xml参数导入servlet

        
          javax.servlet
          servlet-api
          2.5
        
    
    • 1
    • 2
    • 3
    • 4
    • 5

    controller

        @RequestMapping("/request")
        public String request(HttpServletRequest httpServletRequest){
            User user=new User();
            user.setId(1);
            user.setName("张三");
            httpServletRequest.setAttribute("user",user);
            return "show";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    @ModelAttribute

    Spring MVC还可以通过@ModelAttribute注解的方式添加业务数据:

    • 定义一个方法,该方法用来放好填充到业务数据中的对象
    • 给该方法添加@ModelAttribute注解,不是响应请求的业务方法。
     @RequestMapping("/modellAttribute")
        public String modelAttribute(){
            return "show";
        }
    
        @ModelAttribute
        public User getUser(){
            User user=new User();
            user.setId(1);
            user.setName("张三");
            return user;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    @ModelAttribute注解的作用是当Handler接收到一个请求后,无论调用哪个业务方法都会优先调用被@ModelAttribute注解修饰的方法,并将其返回值作为业务数据,再进入到业务方法中,此时业务方法只需要返回视图信息即可,不需要返回业务数据,即使返回业务数据,也会被@ModelAttribute注解修饰的方法返回的数据所覆盖

    域对象中存值都以key-value形式存储的,那么此时key值默认值是物业数据对应的类的类名首字母小写之后的结果。

    如果getUser没有返回值则必须手动在该方法中填充业务数据,使用Map或Model均可

        public void getUser(Model model)
        {
            User user=new User();
            user.setId(1);
            user.setName("张三");
            model.addAttribute("user",user);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    如果同时存在两个@ModelAttribute注解方法,直接给Model进行装载的方法优先级更高。

    业务数据绑定到session域对象

    • HttpSession

    通过session传递

        @RequestMapping("/session")
        public String session(HttpSession session){
            User user=new User();
            user.setId(1);
            user.setName("张三");
            session.setAttribute("user",user);
            return "show";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    将作用域改为sessionScope

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ page isELIgnored="false"%>
    
    
        Title
    
    
    ${sessionScope.user}
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    @SessionAttribute

    @SessionAttribute注解不是给方法添加的,而是给类添加的。

    @Controller
    @RequestMapping("/view")
    @SessionAttributes("user")
    public class ViewHandler {
        @RequestMapping("/sessionAnnotation")
        public ModelAndView sessionAnnotation(){
            ModelAndView modelAndView=new ModelAndView("show");
            User user=new User();
            user.setId(1);
            user.setName("张三");
            modelAndView.addObject("user",user);
            return modelAndView;
        }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    @SessionAttributes通过key值定位,多个key值时可以写作:

    @SessionAttributes(value={"user","student"})
    
    • 1

    @SessionAttributes也可以通过对象名添加

    @SessionAttributes(types=User.class)
    
    • 1

    @SessionAttributes(type={User.class,Address.class})
    
    • 1

    只要给类加了@SessionAttributes注解之后,无论类中的哪个业务方法被访问,将业务数据绑定到request域对象的同时,也会将业务数据绑定到session域对象中,也就是说request和session对象会同时存在业务数据,前提是request域中的key值需要和@SessionAttributes注解中的value值一致。

    Spring MVC的自定义数据类型转换器

    1. 创建DateConverter类,并实现org.springframework.core.convert.converter.Converter接口,成为一个自定义数据类型转换器,需要指定泛型,表示将String类型转为Date类型
    import org.springframework.core.convert.converter.Converter;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class DateConverter implements Converter {
        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 (Exception e){e.printStackTrace();}
            return null;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在springmvc.xml中配置conversionService bean,这个bean是org.springframework.context.support.ConversionServiceFactoryBean的实例化对象,同时bean中必须包含一个converters属性,在其中注册所有需要使用的自定义转换器

        
            
                
                    
                        
                    
                
            
        
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    添加一个Student类进行转换
    Student类

    import lombok.Data;
    
    @Data
    public class Student {
        private Integer id;
        private String name;
        private Integer age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    springmvc.xml添加

        
            
                
                    
                
            
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    添加转换类StudentConverter

    import com.test.entity.Student;
    import org.springframework.core.convert.converter.Converter;
    
    public class StudentConverter implements Converter {
        @Override
        public Student convert(String s) {
            String[] args=s.split("-");
            Student student=new Student();
            student.setId(Integer.parseInt(args[0]));
            student.setName(args[1]);
            student.setAge(Integer.parseInt(args[2]));
            return student;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    添加jsp页面student.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    
        Title
    
    
        
    (1-张三-22)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    注册controller

    import com.test.entity.Student;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    
    @Controller
    @RequestMapping(value = "/converter")
    public class ConvertHandler {
        @RequestMapping("/student")
        @ResponseBody
        public Student student(Student student, HttpServletResponse response)
        {
            response.setCharacterEncoding("UTF-8");
            return student;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    Spring MVC与RESTful集成

    • 什么是RESTful?
      RESTful是当前比较流行的一种互联网软件架构模型,通过统一的规范完成不同终端的数据访问和交互,REST全称是Representational State Transfer(资源表现层状态转换)

    RESTful的优点:结构清晰、有统一的标准、拓展性好

    • Resources

    资源指的是网络中的某个具体文件,类型不限,可以是文本、图片、视频、音频、数据流等,是网络中真实存在的实体。可以通过统一资源定位符找到这个实体,URI,每个资源都有一个特定的URI,通过URI就可以找到一个具体的资源。

    • Pepresentation

    资源表现层,资源的具体表现形式,例如一段文字,可以使用TXT、HTML、XML、JSON等不同的形式来描述它。

    • State Transfer

    状态转化是指客户端和服务端之间的数据交互,因为HTTP请求不能传输数据的状态,所有的状态都保存在服务端,如果客户端希望访问服务端的数据,就需要使其发生状态改变,同时这种状态转化是建立在表现层上的,完成转换就表示资源的表现形式发生了改变。

    RESTful概念比较抽象,特点有两个:

    1. URL传参更加简洁
    • 传统形式 URL http://localhost:8080/query/findById?id=1
    • RESTful URL: http://localhost:8080/findById/1
    1. 完成不同终端之间资源共享,RESTful提供了一套规范,不同终端之间只需要遵守该规范,就可以实现数据交互。

    具体来讲就是四种表现形式,HTTP协议中四种请求类型(GET、POST、PUT、DELETE)分别表示四种常规操作,CRUD

    • GET用来获取资源
    • POST用来创建资源
    • PUT用来修改资源
    • DELETE用来删除资源

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

    传统的Web开发中,form只支持GET和POST,不支持DELETE和PUT,通过添加HiddenHttpMethodFilter过滤器,可以将POST请求转为PUT或DELETE。

    HiddenHttpMethodFilter的实现原理

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

    实现步骤

    在form表单中添加隐藏域标签,name为_method,value为DELETE或PUT

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    
        Title
    
    
      
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在web.xml中配置HiddenHttpMethodFilter

      
      
        HiddenHttpMethodFilter
        org.springframework.web.filter.HiddenHttpMethodFilter
      
      
      
        HiddenHttpMethodFilter
        /*
      
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Handler

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.*;
    
    @Controller
    @RequestMapping("/rest")
    public class RESTfulHandler {
        @GetMapping("/find")
        @ResponseBody
        public String find()
        {
            return "Hello";
        }
    
        @PostMapping("/save")
        public void save(){
    
        }
        @PutMapping("/update")
        @ResponseBody
        public String update(){
            return "接收到PUT请求";
        }
    
        @DeleteMapping("/delete")
        @ResponseBody
        public String delete(){
            return "已接受到DELETE请求";
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    一个小案例

    需求分析

    • 添加课程,成功则返回全部课程信息
    • 查询课程,通过id查询对应课程信息
    • 修改课程,成功则返回修改之后的全部课程信息
    • 删除课程,成功则返回删除之后的全部课程信息

    jsp

    • 添加课程 add.jsp
    • 修改课程 edit.jsp
    • 课程展示 index.jsp

    添加jstl依赖

        
        
          jstl
          jstl
          1.2
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    实体类

    private Integer id;
    private String name;
    private Double price;
    
    • 1
    • 2
    • 3

    CourseRepository

    @Repository
    public class CourseRepository {
        private Map courseMap;
    
        public CourseRepository(){
            courseMap=new HashMap<>();
            courseMap.put(1,new Course(1,"Java基础",Double.parseDouble("500")));
            courseMap.put(2,new Course(2,"Java高级",Double.parseDouble("600")));
            courseMap.put(3,new Course(3,"企业级框架",Double.parseDouble("800")));
        }
        public Collection 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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    改写下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"%>
    
    
        Title
    
    
        
                
    编号 名称 价格
    ${course.id} ${course.name} ${course.price}
    修改
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    CourseController

    import com.test.entity.Course;
    import com.test.repository.CourseRepository;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.servlet.ModelAndView;
    
    @Controller
    @RequestMapping("/course")
    public class CourseController {
        @Autowired
        private CourseRepository courseRepository;
    
        @GetMapping("/findAll")
        public ModelAndView findAll(){
                ModelAndView modelAndView=new ModelAndView();
                modelAndView.setViewName("index");
                modelAndView.addObject("list",courseRepository.findAll());
                return modelAndView;
        }
    
        @PostMapping("/save")
        public String save(Course course){
            courseRepository.saveOrUpdate(course);
            return "redirect:/course/findAll";
        }
        @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";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    save.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    
        Title
    
    
      
    课程编号:
    课程名称:
    课程价格:
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    edit.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ page isELIgnored="false"%>
    
    
        Title
    
    
      
    编号:
    名称:
    价格:
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    Spring MVC实现文件的上传下载

    文件上传

    单文件上传
    1. 底层使用的是Apache fileupload组件完成上传功能,SpringMVC只是对其进行了封装,简化开发

    pom.xml引入依赖

        
        
          commons-io
          commons-io
          2.6
        
        
          commons-fileupload
          commons-fileupload
          1.3.3
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    JSP页面

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

    upload.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ page isELIgnored="false" %>
    
    
        Title
    
    
        
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    FileHandler

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.multipart.MultipartFile;
    
    import javax.servlet.http.HttpServletRequest;
    import java.io.File;
    
    @Controller
    @RequestMapping("/file")
    public class FileHandler {
        @PostMapping("/upload")
        public String upload(@RequestParam("img") MultipartFile img, HttpServletRequest request){
            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);
                    request.setAttribute("src","/file/"+fileName);
                }
                catch (Exception e){e.printStackTrace();}
            }
    
            return "upload";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    在springmvc.xml中配解析器

     
    
    • 1
    多文件上传

    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" %>
    
    
        Title
    
    
        
    file1:
    file2:
    file3:
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    controller

        @RequestMapping("/uploads")
        public String uploads(@RequestParam("imgs") MultipartFile[] imgs,HttpServletRequest request){
            List 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 (Exception e){e.printStackTrace();}
            }
                request.setAttribute("list",pathList);
        }
            return "uploads";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    Spring MVC数据校验

    数据校验是每个项目必不可少的模块,SpringMVC提供了两种数据校验的组件:

    • 基于Validator接口进行校验
    • 使用Annotation JSR-303标准校验

    使用基于Validator接口进行校验会复杂一些,具体数据校验的规则需要开发者手动设置。而使用Annotation JSR-303标准会相对简单一些,开发者不需要编写校验规则,直接通过注解的形式给每一条数据添加验证规则,具体操作是直接在实体类的属性上添加对应的校验注解即可。

    基于Validator接口

    例:

    创建实体类:

    import lombok.Data;
    
    @Data
    public class Student {
        private String name;
        private String password;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    自定义数据校验器StudentValidation,实现Validation接口,重写接口的抽象方法,加入校验规则。

    import com.test.Entity.Student;
    import org.springframework.validation.Errors;
    import org.springframework.validation.ValidationUtils;
    import org.springframework.validation.Validator;
    
    public class StudentValidation implements Validator {
        public boolean supports(Class aClass) {
            return Student.class.equals(aClass);
        }
    
        public void validate(Object o, Errors errors) {
            ValidationUtils.rejectIfEmpty(errors,"name",null,"姓名不能为空");
            ValidationUtils.rejectIfEmpty(errors,"password",null,"密码不能为空");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    ValidateHandler.java

    import com.test.Entity.Student;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.validation.BindingResult;
    import org.springframework.validation.annotation.Validated;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @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";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    springmvc.xml配置validator

        
        
    
    • 1
    • 2

    JSP

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
    
    
        Title
    
    
        

    学生登录

    学生姓名:
    学生密码:
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    Annotation JSR-303标准

    Hibernater Validator,通过注解完成校验规则的绑定。
    @Null 只能为null
    @NotNull 不能为null
    @Size 设置数据长度
    @NotEmpty 不能为空

    例:

    pom.xml

        
        
          org.hibernate.validator
          hibernate-validator
          6.0.11.Final
        
        
          javax.validation
          validation-api
          2.0.1.Final
        
        
          org.jboss.logging
          jboss-logging
          3.4.1.Final
        
    
        
        
          javax.xml.bind
          jaxb-api
          2.3.1
        
        
          com.sun.xml.bind
          jaxb-impl
          2.3.0
        
        
          com.sun.xml.bind
          jaxb-core
          2.3.0
        
        
          javax.activation
          activation
          1.1.1
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    创建实体类,通过注解的方式给属性指定校验规则

    import lombok.Data;
    
    import javax.validation.constraints.Email;
    import javax.validation.constraints.NotEmpty;
    import javax.validation.constraints.Pattern;
    import javax.validation.constraints.Size;
    
    @Data
    public class Account {
        @NotEmpty(message = "用户名不能为空")
        private String username;
        @Size(min=6,max=20,message = "密码长度为6-20位")
        private String password;
        @Email(regexp = "^[a-z]([a-z0-9]*[-_]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+[\\.][a-z]{2,3}([\\.][a-z]{2})?$",message = "请输入正确的邮箱")
        private String email;
        @Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "请输入正确的电话格式")
        private String phone;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    业务方法

        @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 "register";
            }
            return "success";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    springmvc.xml

    
    
    • 1

    JSP

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
    
    
        Title
    
    
        

    用户注册

    用户名:
    密码:
    邮箱:
    电话:
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    Spring MVC表单标签库

    例:

    Student实体类

    import lombok.Data;
    
    @Data
    public class Student {
        private Integer id;
        private String name;
        private Integer age;
        private String gender;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    import com.test.entity2.Student;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    @RequestMapping("/student")
    public class StudentHandler {
        
        @RequestMapping("/get")
        public String get(Model model){
            Student student=new Student();
            model.addAttribute("student",student);
            return "student";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    JSP

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@page isELIgnored="false" %>
    
    
        Title
    
    
        

    修改学生信息

    学生编号:
    学生姓名:
    学生年龄:
    学会性别:
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    Handler

    import com.test.entity2.Student;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @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";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    表单标签库的使用

    JSP页面导入Spring MVC表单标签库

    <%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
    
    • 1

    将form表单与表单业务数据进行绑定,通过modelAttribute属性完成绑定,将modelAttribute的值设置为控制器想model对象存值时的name即可

    
        学生编号:
        学生姓名:
        学生年龄:
        学生性别:
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    常用标签

    1.form标签

    
    
    • 1

    渲染的时HTML中的

    ,通过modelAttribute属性绑定具体业务数据。

    2.input标签

    
    
    • 1

    渲染的时HTML中的,form绑定的是业务数据,input标签绑定的是业务数据中的属性值,通过path与业务数据的属性名对应,并支持级联。

    例:

    实体类

    import lombok.Data;
    
    @Data
    public class Address {
        private Integer id;
        private String name;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    import lombok.Data;
    
    @Data
    public class Student {
        private Integer id;
        private String name;
        private Integer age;
        private String gender;
        private Address address;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    JSP

    
        学生编号:
        学生姓名:
        学生年龄:
        学生性别:
        学生地址:
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    Handler

        @RequestMapping("/get")
        public String get(Model model){
            Student student=new Student();
            student.setId(1);
            student.setName("张三");
            student.setAge(22);
            student.setGender("男");
    
            Address address=new Address();
            address.setId(1);
            address.setName("科技路");
            student.setAddress(address);
            model.addAttribute("student",student);
            return "student";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3.password标签

    
    
    • 1

    渲染的是HTML中的通过path与业务数据的属性名对应,password标签的值不会在页面显示。

    4.checkbox标签

    
    
    • 1

    渲染的是HTML中的,通过path与业务数据的属性名对应,可以绑定boolean、数组和集合。

    如果绑定boolean类型的变量,该变量值为true则表示选中,false表示不选中。

    JSP

        checkbox:
    
    • 1

    如果绑定数组和集合类型,集合中的元素等于checkbox的value值,则该项选中,否则不选中。

    JSP

        读书
        看电影
        打游戏
        听音乐
        旅行
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5.checkboxs标签

    
    
    • 1

    渲染的是HTML中的一组,这里需要结合items和path两个属性来使用,items绑定被遍历的集合或数组,path绑定选中的集合或数组items是全部选型,path为默认选中的选型

            student.setHobby(Arrays.asList("读书","看电影","旅行"));
            student.setSelectHobby(Arrays.asList("读书","看电影"));
    
    • 1
    • 2

    JSP

        
    
    • 1

    需要注意的是path可以直接绑定业务数据的属性,items则需要通过EL表达式从域对象中取值,不能直接写属性名。

    6.radiobutton

    
    
    • 1

    渲染的是HTML中的一个,绑定的数据与标签的value值相等为选中状态,否则为不选中状态。

        private Integer radioId;
    
    • 1

    JSP

        
    • 1
    • 2

    7.radiobuttons标签

    
    
    • 1

    渲染的是HTML中的一组,这里需要结合items和path两个属性来使用,item绑定被遍历的集合或数组,path绑定被选中的值,items是全部选型,path为默认选中的选型。

            Map gradeMap=new HashMap<>();
            gradeMap.put(1,"一年级");
            gradeMap.put(2,"二年级");
            gradeMap.put(3,"三年级");
            gradeMap.put(4,"四年级");
            gradeMap.put(5,"五年级");
            gradeMap.put(6,"六年级");
            student.setGradeMap(gradeMap);
            student.setSelectGrade(3);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    JSP

        
    
    • 1

    8.select标签

    
    
    • 1

    渲染的是HTML中的一个
    :



    "/> "/>

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    【linux】htop 命令行工具使用
    字典树(随学)
    旭日x3派上实时订阅yolov5识别到的内容并通过串口发送到stm32f10系上并通过oled实时显示的stm32代码怎么写
    PRT(Precomputed Radiance Transfer【2002】)原理实现
    结合Redux Toolkit使用React Redux
    java彻底搞懂单例模式
    JAVA计算机毕业设计网上家教信息管理系统(附源码、数据库)
    Python JSON
    java集成datax
    Datawhale 202208 GitModel |线性规划 整数规划 多目标规划 灵敏度分析
  • 原文地址:https://blog.csdn.net/weixin_41489136/article/details/128081013