美文网首页
SpringMVC简介及实用接收请求方式

SpringMVC简介及实用接收请求方式

作者: 写程序踩过的坑 | 来源:发表于2021-03-26 16:26 被阅读0次

    SpringMVC简介及实用接收请求方式

    什么是MVC?

    在 JavaEE 开发中,几乎全都是基于 B/S (浏览器服务器)架构的开发。那么在 B/S 架构中,系统标准的三层架构包括:表现层、业务层、持久层。而MVC在表现层!

    SpringMVC

    全名叫 Spring Web MVC,是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级

    Web 框架,属于 SpringFrameWork 的后续产品。

    Spring MVC和Struts2一样,都是 为了解决表现层问题 的web框架,它们都是基于 MVC 设计模

    式的。这些表现层框架的主要职责就是处理前端HTTP请求。

    作用:

    1)接收请求

    2)返回响应,跳转页面

    RESTful风格

    REST(Representational State Transfer)

    Restful 的优点:它结构清晰、符合标准、易于理解、扩展⽅便。

    原有的url设计

    localhost:8080/user/queryUserById.action?id=3

    有了RESTful 变成:

    http://localhost:8080/user/3
    

    RESTful风格即使请求路径相同,但状态操作(get,post,put,delete)不同,都可以请求到想要的接口。

    通过项目讲解

    一 springmvc-demo

    1 传参方式和后台接

    请求参数绑定:说白了SpringMVC如何接收请求参数?

    • 单个或少数传参法

    原servlet接收一个整型参数:

    1)String ageStr = request.getParameter("age");

    2) Integer age = Integer.parseInt(ageStr);

    SpringMVC框架对Servlet的封装,简化了servlet的很多操作

    SpringMVC在接收整型参数的时候,直接在Handler方法中声明形参即可

    @RequestMapping("xxx")
    
    public String handle(Integer age) {
    
    System.out.println(age);
    
    }
    

    注意:

    1 参数绑定:取出参数值绑定到handler方法的形参上,传递的参数名和声明的形参名称保持一致

    2 对于布尔类型(Boolean)的参数, 请求的参数值只接收true或false,或者1或0

    方法参数名和传递参数名不一致呢?

    可以使用@RequestParam注解,如

     /*
         * SpringMVC 接收简单数据类型参数  url:/demo/handle03?id=1
         *
         * 注意:接收简单数据类型参数,直接在handler方法的形参中声明即可,框架会取出参数值然后绑定到对应参数上
         * 要求:传递的参数名和声明的形参名称保持一致
         */
        @RequestMapping("/handle03")
        public ModelAndView handle03(@RequestParam("ids") Integer id,Boolean flag) {
    
            Date date = new Date();
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("date",date);
            modelAndView.setViewName("success");
            return modelAndView;
        }
    

    建议:使用包装类型,因为基础数据类型不可以为null

    • url传参
    @RequestMapping(value = "/handle/{id}",method ={RequestMethod.GET})
    
    public ModelAndView handleGet(@PathVariable("id") Integer id) {
    
    }
    
    • 绑定Pojo类型参数

    1 接收pojo类型参数,直接形参声明即可,类型就是Pojo的类型,形参名无所谓

    2 但是要求传递的参数名必须和Pojo的属性名保持一致

    前端代码

    测试用例:SpringMVC接收pojo类型参数
    
    <a href="/demo/handle04?id=1&amp;name=zhangsan">点击测试</a>
    

    后台 (注意:这里要加get set方法)

    public class User {
    
        private Integer id;
        
        private String name;
        
        }
        
        public ModelAndView handle04(User user) {
        
        Date date = new Date();
        
        ModelAndView modelAndView = new ModelAndView();
        
        modelAndView.addObject("date",date);
        
        modelAndView.setViewName("success");
        
        return modelAndView;
    
    }
    
    • SpringMVC接收pojo包装类型参数

    前端代码

    测试用例:SpringMVC接收pojo包装类型参数
    
    <a href="/demo/handle05?user.id=1&amp;user.name=zhangsan">点击测试</a>
    

    后台(注意:这里要加get set方法)

    public class QueryVo {
    
        private String mail;
        
        private String phone;
        
        // 嵌套了另外的Pojo对象
        
        private User user;
    
    }
    
    /\*
    
    * SpringMVC接收pojo包装类型参数 url:/demo/handle05?user.id=1&user.username=zhangsan
    * 不管包装Pojo与否,它首先是一个pojo,那么就可以按照上述pojo的要求来
    * 1、绑定时候直接形参声明即可
    * 2、传参参数名和pojo属性保持一致,如果不能够定位数据项,那么通过属性名 + "." 的方式进一步锁定数据
    *
    
    \*/
    
    @RequestMapping("/handle05")
    
    public ModelAndView handle05(QueryVo queryVo) {
    
        Date date = new Date();
        
        ModelAndView modelAndView = new ModelAndView();
        
        modelAndView.addObject("date",date);
        
        modelAndView.setViewName("success");
        
        return modelAndView;
    
    }
    
    • @RequstBody @ResponseBody

    用Ajax Json交互

    1)前端到后台:前端ajax发送json格式字符串,后台直接接收为pojo参数,使用注解@RequstBody

    2)后台到前端:后台直接返回pojo对象,前端直接接收为json对象或者字符串,使用注解

    @ResponseBod

    Spring MVC 使用 Json 交互所需jar包

    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.0</version>
    </dependency>
    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
    </dependency>
    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.0</version>
    </dependency>

    前端jsp及js代码
    <h2>Ajax json交互
    </h2>

     $(function () {
                $("#ajaxBtn").bind("click",function () {
                    // 发送ajax请求
                    $.ajax({
                        url: '/demo/handle07',
                        type: 'POST',
                        data: '{"id":"1","name":"李四"}',
                        contentType: 'application/json;charset=utf-8',
                        dataType: 'json',
                        success: function (data) {
                            alert(data.name);
                        }
                    })
                })
            })
    

    后台controller代码

    @RequestMapping("/handle07")
    
    // 添加@ResponseBody之后,不再⾛视图解析器那个流程,⽽是等同于response直接输出
    
    数据
    
    public @ResponseBody User handle07(@RequestBody User user) {
    
        // 业务逻辑处理,修改name为张三丰
    
        user.setName("张三丰");
    
        return user;
    
    }
    
    • 处理multipart形式的数据

    文件上传

    原生servlet处理上传的文件数据的,springmvc是对serlvet的封装

    所需jar包

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

    1.3.1

    配置文件上传解析器
    前端form

     <div>
            <h2>multipart 文件上传</h2>
            <fieldset>
                <%--
                    1 method="post"
                    2 enctype="multipart/form-data"
                    3 type="file"
                --%>
                <form method="post" enctype="multipart/form-data" action="/demo/upload">
                    <input type="file" name="uploadFile"/>
                    <input type="submit" value="上传"/>
                </form>
            </fieldset>
        </div>
    

    注意
    1 method="post" 必须是post
    2 enctype="multipart/form-data"
    3 type="file"

    后台接收Handler

      /**
         * 文件上传
         * @return
         */
        @RequestMapping(value = "/upload")
        public ModelAndView upload(MultipartFile uploadFile,HttpSession session) throws IOException {
    
            // 处理上传文件
            // 重命名,原名123.jpg ,获取后缀
            String originalFilename = uploadFile.getOriginalFilename();// 原始名称
            // 扩展名  jpg
            String ext = originalFilename.substring(originalFilename.lastIndexOf(".") + 1, originalFilename.length());
            String newName = UUID.randomUUID().toString() + "." + ext;
    
            // 存储,要存储到指定的文件夹,/uploads/yyyy-MM-dd,考虑文件过多的情况按照日期,生成一个子文件夹
            String realPath = session.getServletContext().getRealPath("/uploads");
            String datePath = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            File folder = new File(realPath + "/" + datePath);
    
            if(!folder.exists()) {
                folder.mkdirs();
            }
    
    
            // 存储文件到目录
            uploadFile.transferTo(new File(folder,newName));
    
    
            // TODO 文件磁盘路径要更新到数据库字段
    
            Date date = new Date();
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("date",date);
            modelAndView.setViewName("success");
            return modelAndView;
        }
    
    • 基于Flash属性的跨重定向请求数据传递

    重定向时请求参数会丢失,我们往往需要重新携带请求参数,我们可以进行动参数拼接如下:

    return "redirect:handle01?name=" + name;

    但是上述拼接参数的方法属于get请求,携带参数长度有限制,参数安全性也不够,此时,我们可以使用SpringMVC提供的flash属性机制,向上下行中添加flash属性,框架会在session中记录该属性值,当跳转到之后框架会自动删除flash属性,不需要我们手动删除,通过这种方式进行重定向参数传递,参数长度和安全性都得到了保障,如下:

    /**
    * SpringMVC 重定向时参数传递的问题
    * 转发:A 找 B 借钱400,B没有钱但是悄悄的找到C借了400块钱给A
    * url不会变,参数也不会丢失,一个请求
    * 重定向:A 找 B 借钱400,B 说我没有钱,你找别人借去,那么A 又带着400块的借钱需求找到C
    * url会变,参数会丢失需要重新携带参数,两个请求
    */

    @RequestMapping("/handleRedirect")
    public String handleRedirect(String name,RedirectAttributes redirectAttributes) {
    
        //return "redirect:handle01?name=" + name;  // 拼接参数安全性、参数长度都有局限
        // addFlashAttribute方法设置了一个flash类型属性,该属性会被暂存到session中,在跳转到页面之后该属性销毁
        redirectAttributes.addFlashAttribute("name",name);
        return "redirect:handle01";
    
    }
    
    • 传入Map、Model和ModelMap参数,用于跳转

    SpringMVC在handler方法也可以传入Map、Model和ModelMap参数,并向这些参数中保存数据(放入到请求域),都可以在页面获取到。

    eg:

    @RequestMapping("/handle11")
    
    public String handle11(ModelMap modelMap) {
    
    }
    

    它们之间是什么关系?

    • 运行时的具体类型都是BindingAwareModelMap,相当于给BindingAwareModelMap中保存的数据都会放在请求域中。

    相关文章

      网友评论

          本文标题:SpringMVC简介及实用接收请求方式

          本文链接:https://www.haomeiwen.com/subject/bmajhltx.html