• 【SSM】SpringMVC系列——SpringMVC注解式开发



    活动地址:CSDN21天学习挑战赛

    第2章 SpringMVC注解式开发

    2.1@RequestMapping定义请求规则

    1.1.1 指定模块名称

    • 通过@RequestMapping 注解可以定义处理器对于请求的映射规则。

    • 该注解可以注解在方法上,也可以注解在类上,但意义是不同的。

    • value 属性值常以“/”开始。

    • @RequestMapping 的 value 属性用于定义所匹配请求的 URI。

    • 一个@Controller 所注解的类中,可以定义多个处理器方法。

    • 不同的处理器方法所匹配的 URI 是不同的。这些不同的 URI 被指定在注解于方法之上的@RequestMapping 的value 属性中。但若这些请求具有相同的 URI 部分,则这些相同的 URI部分可以被抽取到注解在类之上的@RequestMapping 的 value 属性中。此时的这个 URI 表示模块(相当于包)的名称。URI 的请求是相对于 Web 的根目录。

    • 换个角度说,要访问处理器的指定方法,必须要在方法指定 URI 之前加上处理器类前定义的模块名称。

    示例:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1MWomNYS-1658935337946)(../../../../Pictures/Spring/wps5.jpg)]

    提取后

    @Controller 
    @RequestMapping("/zar")
    public class HelloSpringMvc { 
        //相当于一个控制器处理的方法
        @RequestMapping("/hello") 
        public String one() {
            return "main";
        }
        @RequestMapping("/two")
        public String two() { 
            return "main"; 
        } 
        //客户端的请求:
        // 
    // }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.1.1对请求提交方式的定义

    • 对于@RequestMapping,其有一个属性 method,用于对被注解方法所处理请求的提交方式进行限制,即只有满足该 method 属性指定的提交方式的请求,才会执行该被注解方法。
    • Method 属性的取值为 RequestMethod 枚举常量。常用的为 RequestMethod.GET 与 RequestMethod.POST,分别表示提交方式的匹配规则为 GET 与 POST 提交。
    @RequestMapping(value = "/hello", method = RequestMethod.POST)
    public String one() { 
        return "main";
    }
    
    • 1
    • 2
    • 3
    • 4

    以上处理器方法只能处理 POST 方式提交的请求。

    客户端浏览器常用的请求方式,及其提交方式有以下几种:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s1bpzH4X-1658935337947)(../../../../Pictures/Spring/wps6.jpg)]

    也就是说,只要指定了处理器方法匹配的请求提交方式为 POST,则相当于指定了请求发送的方式:要么使用表单请求,要么使用 AJAX 请求。其它请求方式被禁用。

    当然,若不指定 method 属性,则无论是 GET 还是 POST 提交方式,均可匹配。即对于请求的提交方式无要求。

    (1) post提交方式

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m2sz14iw-1658935337948)(../../../../Pictures/Spring/wps7.jpg)]

    (2)get提交方式

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-anq1DpGv-1658935337948)(../../../../Pictures/Spring/wps8.jpg)]

    2.2 五种数据提交的方式

    前四种数据注入的方式,会自动进行类型转换。但无法自动转换日期类型。

    (1)单个数据注入

    在方法中声明一个和表单提交的参数名称相同的参数,由框架按照名称直接注入。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qyoMZBKh-1658935337948)(../../../../Pictures/Spring/wps9.jpg)]

    (2)对象封装注入

    在方法中声明一个自定义的实体类参数,框架调用实体类中相应的setter方法注入属性值,只要保证实体类中成员变量的名称与提交请求的name属性值一致即可。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-twqOep6p-1658935337948)(../../../../Pictures/Spring/wps10.jpg)]

    (3)动态占位符提交(仅用于超链接)

    使用框架提供的一个注解@PathVariable,将请求url中的值作为参数进行提取,只能是超链接。restful风格下的数据提取方式。restful是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KuI8cIUM-1658935337949)(../../../../Pictures/Spring/wps11.jpg)]

    (4)请求参数名称与形参名称不一致

    请求与形参中的名字不对应,可以使用

    @RequestParam(value="name1",required=true)String namea
    
    • 1

    来进行参数名称绑定。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V3dbxazs-1658935337949)(../../../../Pictures/Spring/wps12.jpg)]

    (5)使用HttpServletRequest对象提取

    在方法参数中声明一个request对象,使用request的getParameter()获取表单提交的数据,这样得到的数据还要手工进行数据类型的转换。

    public String five(HttpServletRequest request){ 
        int age=new Integer(request.getParameter("stuage")); 
        String name=request.getParameter("stuname"); 
        System.out.println(age+"*********"+name);
        return "main";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.3请求参数中文乱码解决

    对于前面所接收的请求参数,若含有中文,则会出现中文乱码问题。Spring 对于请求参数中的中文乱码问题,给出了专门的字符集过滤器: spring-web-5.2.5.RELEASE.jar 的org.springframework.web.filter 包下的 CharacterEncodingFilter 类。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B5Otpgbl-1658935337949)(../../../../Pictures/Spring/wps13.jpg)]

    (1)解决方案

    在 web.xml 中注册字符集过滤器,即可解决 Spring 的请求参数的中文乱码问题。不过,最好将该过滤器注册在其它过滤器之前。因为过滤器的执行是按照其注册顺序进行的。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EbnEraw0-1658935337949)(../../../../Pictures/Spring/wps14.jpg)]

    (2)源码分析

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1sCdufXk-1658935337950)(../../../../Pictures/Spring/wps15.jpg)]

    2.4处理器方法的返回值

    使用@Controller 注解的处理器的方法,其返回值常用的有四种类型:

    • 第一种:ModelAndView
    • 第二种:String
    • 第三种:无返回值void
    • 第四种:返回对象类型

    2.4.1返回 ModelAndView

    • 若处理器方法处理完后,需要跳转到其它资源,且又要在跳转的资源间传递数据,此时处理器方法返回 ModelAndView 比较好。
    • 当然,若要返回 ModelAndView,则处理器方法中需要定义 ModelAndView 对象。
    • 在使用时,若该处理器方法只是进行跳转而不传递数据,或只是传递数据而并不向任何资源跳转(如对页面的 Ajax 异步响应),此时若返回 ModelAndView,则将总是有一部分多余:要么 Model 多余,要么 View 多余。即此时返回 ModelAndView 将不合适。较少使用。

    2.4.2返回 String

    处理器方法返回的字符串可以指定逻辑视图名,通过视图解析器解析可以将其转换为物理视图地址。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XfgsNFiN-1659515140114)(../../../../Pictures/Spring/wps16.jpg)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F3tsVqvt-1659515140117)(../../../../Pictures/Spring/wps17.jpg)]
    在这里插入图片描述

    当然,也可以直接返回资源的物理视图名。不过,此时就不需要再在视图解析器中再配置前辍与后辍了。

    在这里插入图片描述

    2.4.1无返回值void

    对于处理器方法返回 void 的应用场景,应用在AJAX 响应处理。若处理器对请求处理后,无需跳转到其它任何资源,此时可以让处理器方法返回 void。我们SSM整合案例中的分页使用的就是无返回值。

    2.4.2返回对象Object

    • 处理器方法也可以返回 Object 对象。这个 Object 可以是 Integer,自定义对象,Map,List 等。
    • 但返回的对象不是作为逻辑视图出现的,而是作为直接在页面显示的数据出现的。
    • 返回对象,需要使用@ResponseBody 注解,将转换后的 JSON 数据放入到响应体中。
    • Ajax请求多用于Object返回值类型。
    • 由于转换器底层使用了Jackson 转换方式将对象转换为JSON 数据,所以需要添加Jackson的相关依赖。

    项目案例:使用ajax请求返回一个JSON结构的学生.

    实现步骤:

    A.在pom.xml文件中添加依赖

      <dependency>
    
       <groupId>com.fasterxml.jackson.coregroupId>
    
       <artifactId>jackson-databindartifactId>
    
       <version>2.9.8version>
    
      dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    B.添加jQuery的函数库,在webapp目录下,新建js目录,拷贝jquery-3.3.1.js到目录下

    C.在页面添加jQuery的函数库的引用

       <script src="js/jquery-3.3.1.js"></script>
    
    • 1

    D.发送ajax请求

    function show() {
    
         $.ajax({
           url:"${pageContext.request.contextPath}/ajax.action",
           type:"post",
           dataType:"json",
           success:function (stu) {
             $("#oneStu").html(stu.name+"------"+stu.age);
           }
         });
       }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    E.开发action

    @Controller
    public class AjaxDemo {
        @RequestMapping("/ajax")
        @ResponseBody  //此注解用来解析ajax请求
        public Object ajax(){
            Student stu = new Student("张三",22);
            return stu;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    F.在springmvc.xml文件中添加注解驱动

     <mvc:annotation-driven>mvc:annotation-driven>
    
    • 1

    G.index.jsp页面

      ajax访问服务器,返回一个学生
       
    • 1
    • 2

    2.5SpringMVC的四种跳转方式

    • 默认的跳转是请求转发,直接跳转到jsp页面展示
    • 使用框架提供的关键字redirect:,进行一个重定向操作,包括重定向页面和重定向action,
    • 使用框架提供的关键字forward:,进行服务器内部转发操作,包括转发页面和转发action。
    • 当使用redirect:和forward:关键字时,视图解析器中前缀后缀的拼接就无效了。

    页面部分:

     
    请求转发页面(默认)
    请求转发action
    重定向页面
    重定向action
    • 1
    • 2
    • 3
    • 4
    • 5

    Controller部分:

    @Controller
    public class JumpAction {  
        @RequestMapping("/one")   
        public String one(){    
            System.out.println("请求转发页面(默认)"); 
            //以前的访问方式     //request.getRequestDispatcher("/admin/main.jsp").forward(request,response);  
            //观察地址栏的变化: http://localhost:8080/one.action    
            //return "main"; //默认的访问方式是自动拼接前缀和后缀进行跳转   
            return "forward:/fore/user.jsp";//只要使用了forward:就可以屏蔽前缀和后缀的拼接,自己手工构建返回的全部路径+.jsp   
        }  
        @RequestMapping("/two") 
        public String two(){   
            System.out.println("请求转发action");  
            //观察地址栏的变化:  http://localhost:8080/two.action
            return "forward:/other.action"; 
            //不使用forward:,就会是这样的路径 /admin/other.action/.jsp
        } 
        @RequestMapping("/three")  
        public String three(){  
            System.out.println("重定向页面");   
            //观察地址栏的变化 http://localhost:8080/admin/main.jsp 
            return "redirect:/admin/main.jsp";
            //只要使用了redirect:就可以屏蔽前缀和后缀的拼接  
        }  
        @RequestMapping("/four")
        public String four(){ 
            System.out.println("重定向action"); 
            //观察地址栏的变化 http://localhost:8080/other.action    
            return "redirect:/other.action";
            //只要使用了redirect:就可以屏蔽前缀和后缀的拼接
        } 
    }
    
    • 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

    2.6SpringMVC支持的默认参数类型

    这些类型只要写在方法参数中就可以使用了。

    1)HttpServletRequest 对象

    2)HttpServletResponse 对象

    3)HttpSession 对象

    4)Model/ModelMap 对象

    5)Map对象

    示例:

    @Controller
    public class ParamAction {
        @RequestMapping("/param") 
        public String param(HttpServletRequest request,    
                            HttpServletResponse response,  
                            HttpSession session,     
                            Model model,    
                            ModelMap modelMap,    
                            Map map){   
            //Map ,Model,ModelMap,request都使用请求作用域进行传值, 
            //所以必须使用请求转发的方式进行跳转,否则丢失数据
            Student stu = new Student("张三",22);  
            request.setAttribute("requestStu",stu); 
            session.setAttribute("sessionStu",stu);    
            modelMap.addAttribute("modelMapStu",stu); 
            model.addAttribute("modelStu",stu);  
            map.put("mapStu",stu);   
            return "main"; //切记请求转发跳转  
            // return "redirect:/admin/main.jsp";//会丢失数据 
        } 
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    注意Model,Map,ModelMap都使用的是request请求作用域,意味着只能是请求转发后,页面才可以得到值

    2.7日期处理

    2.7.1 日期注入

    日期类型不能自动注入到方法的参数中。需要单独做转换处理。

    使用@DateTimeFormat注解,需要在springmvc.xml文件中添加 标签。

    (1)在方法的参数上使用@DateTimeFormat注解

    @RequestMapping("/submitone")
    public String submitdateone(
        @DateTimeFormat(pattern="yyyy-MM-dd")  
        Date mydate){  
        System.out.println(mydate);   
        return "dateShow"; 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (2)在类的成员setXXX()方法上使用@DateTimeFormat注解

    @DateTimeFormat(pattern="yyyy-MM-dd")
    public void setDate(Date date) { 
        this.date = date;
    }
    
    • 1
    • 2
    • 3
    • 4

    但这种解决方案要在每个使用日期类型的地方都去添加使用@DateTimeFormat注解,比较麻烦,我们可以使用@InitBinder注解来进行类中统一日期类型的处理。

    (3)@InitBinder注解解决类中日期问题

    @InitBinder 
    public void initBinder(WebDataBinder dataBinder) { 
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd"); 
        dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(sf, true));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这样在类中出现的所有日期都可以进行转换了。

    2.7.2 日期显示

    (1)JSON中的日期显示

    需要在类中的成员变量的getXXX方法上加注解.

    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
    public Date getDate() { 
        return date; 
    }
    
    • 1
    • 2
    • 3
    • 4

    (2)JSP页面的日期显示

    需要使用国际化标签,先添加依赖

    <dependency> 
        <groupId>jstlgroupId> 
        <artifactId>jstlartifactId>
        <version>1.2version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    导入国际化的标签库

    <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
    
    • 1

    再使用标签显示日期

    <c:forEach items="${list}" var="stu"> ${stu.name}-------${stu.age}-------
        <fmt:formatDate value="${stu.date}" pattern="yyyy-MM-dd">
    
    • 1
    • 2

    2.8 标签的使用

    • 会自动注册两个bean,分别为**DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter。**是springmvc为@controller分发请求所必须的。
    • 除了注册了这两个bean,还提供了很多支持。

    1)支持使用ConversionService 实例对表单参数进行类型转换;

    2)支持使用 @NumberFormat 、@DateTimeFormat;

    3)注解完成数据类型的格式化;

    4)支持使用 @RequestBody 和 @ResponseBody 注解;

    5)静态资源的分流也使用这个标签;

    2.9资源在WEB-INF目录下

    • 很多企业会将动态资源放在WEB-INF目录下,这样可以保证资源的安全性。
    • 在WEB-INF目录下的动态资源不可以直接访问,必须要通过请求转发的方式进行访问。
    • 这样避免了通过地址栏直接对资源的访问。重定向也无法访问动态资源。

    项目案例:

    页面结构图:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A2X3JkDI-1659515140118)(../../../../Pictures/Spring/wps19.jpg)]

    action:

    @Controller
    public class ShowAction { 
        @RequestMapping("/showIndex")  
        public String showIndex(){ 
            System.out.println("index............."); 
            return "index"; 
        }  
        @RequestMapping("/showMain") 
        public String showMain(){   
            System.out.println("main.............");
            return "main";
        }  
        @RequestMapping("/showLogin") 
        public String showLogin(){    
            System.out.println("login............."); 
            return "login"; 
        }
        @RequestMapping("/login")  
        public String login(String name, String pwd, HttpServletRequest request){ 
            if("admin".equals(name) && "123".equals(pwd)){  
                return "main"; 
            }    
            request.setAttribute("msg","用户名或密码不正确!"); 
            return "login"; 
        }
    }
    
    • 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

    运行结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ClliOchu-1659515140119)(../../../../Pictures/Spring/wps20.jpg)]

  • 相关阅读:
    使用领域引导图卷积神经网络GCNN增强基于脑电图EEG的神经疾病诊断完整代码
    基于poi和JavaBean的excel导出
    做外贸站群效果怎么样?独立站站群是什么?
    汉诺塔-python递归
    Git——新建本地仓库并上传到Gitee
    spark封神之路(3)-spark运行架构
    ElasticSearch(四):ES nested嵌套文档与父子文档处理
    FPGA中串口通信的时钟频率和波特率计数
    Java6种单例模式写法
    UVa11595 Crossing Streets EXTREME
  • 原文地址:https://blog.csdn.net/m0_61163395/article/details/126143309