动力节点 SpringMVC P21-32

哔哩哔哩参考链接
笔记参考链接

(一)对象接收参数方式

当形参过多时,仍使用逐个接收参数的方式非常繁琐,这里介绍对象接收参数的方式。
1、复制一份项目代码,炮制上一期的方法,重命名为ch03 recevieparam2-DuiXiang。
先在index.jsp中添加代码:

    <p>使用java对象接收请求参数</p>
    <form action="receiveObject.do" method="post">
        姓名:<input type="text" name="name"><br/>
        年龄:<input type="text" name="age"><br/>
        <input type="submit" value="提交参数">
    </form>

2、定义一个类对象。在java下面新建com.bjpowernode.vo的package,在下面新建Student的class。
动力节点 SpringMVC P21-32_第1张图片
(1)定义了两个属性name和age,右键选择Genrate,选择Getter and Setter,选中两个属性,自动为两个属性生成对应的get和set方法。
(2)然后创建一个无参构造,即右键选择Genrate,选择Constructor,点击Select None,即可生成无参构造方法Student。
输入sout按Tab键自动补齐System.out.println。
(3)创建一个toString方法,即右键选择Genrate,选择toString,默认全选中了所有属性,点击OK即可。

package com.bjpowernode.vo;

//保存请求参数值的一个普通类
public class Student {
    //属性值要和请求参数值一样
    private String name;
    private int age;

    public Student() {
        System.out.println("===Student的无参数构造方法===");

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("setName"+name);
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        System.out.println("setAge"+age);
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

3、MyController加上receiveObject方法,传入参数是Student对象。

/**
     * 处理器方法的形参是java对象,这个对象的属性名要求和请求中参数名一致
     * 框架会创建形参的java对象,给属性赋值。请求中的参数是name,框架会调用setName()完成赋值。类似于set注入
     */
    @RequestMapping(value = "/receiveObject.do")
    public ModelAndView receiveObject(Student student){

        System.out.println("receiveObject,name="+student.getName()+"  age="+student.getAge());
        ModelAndView mv = new ModelAndView();
        mv.addObject("myname",student.getName());
        mv.addObject("myage",student.getAge());
        mv.addObject("student",student);
        mv.setViewName("show");
        return mv;
    }

4、更改show.jsp中的代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>show.jsp从request作用域获取数据</h3><br/>
    <h3>myname数据:${myname}</h3>
    <h3>myage数据:${myage}</h3>
    <h3>student数据:${student}</h3>
</body>
</html>

5、运行
动力节点 SpringMVC P21-32_第2张图片
动力节点 SpringMVC P21-32_第3张图片
控制台显示:
动力节点 SpringMVC P21-32_第4张图片

(二)处理器方法的返回值

处理器方法的返回值分为四种:返回ModelAndView(适合既需要数据又需要视图的情况,视图需要forward转发)、返回String、返回void、返回对象Object

2.1 返回String

1、适用于只需要页面跳转的工作,相当于view,只需要视图的情况。
处理器方法返回的字符串可以指定逻辑视图名,通过视图解析器解析可以将其转换为物理视图地址。
2、代码编写
(1)复制项目,更名为ch04 return-String。先修改index.jsp:

	<p>处理器方法返回String表示视图名称</p>
    <form action="returnString-view.do" method="post">
        姓名:<input type="text" name="name"><br/>
        年龄:<input type="text" name="age"><br/>
        <input type="submit" value="提交参数">
    </form>

(2)修改MyController,这时我们写的doReturnView方法前面的返回参数类型不再是ModelAndView了,而是String。因为我们在springmvc.xml文件中配置了视图解析器,所以写跳转页面时只要写return “show”,即可完成页面跳转。如果页面跳转后还想加一些数据,可以用request手动加。

/**
     *处理器方法返回String--表示逻辑视图名称,需要配置视图解析器(在springmvc.xml文件中)
     */
    @RequestMapping(value="/returnString-view.do")
    public String doReturnView(HttpServletRequest request,String name,Integer age){
        System.out.println("doReturnView,name="+name+" age="+age);
        //2、如果还需要添加数据的话,可以手动添加数据到request作用域
        request.setAttribute("myname",name);
        request.setAttribute("myage",age);
        //show:逻辑视图名称,因为项目中配置了视图解析器
        //1、框架对视图执行forward转发操作,这样可以直接跳转到另一个页面了
        return "show";
    }

(3)启动Tomcat运行:
动力节点 SpringMVC P21-32_第5张图片
动力节点 SpringMVC P21-32_第6张图片
3、如果不配置视图解析器呢?那么要表示成完整视图路径。
(1)修改index.jsp,增加一个表单:

    <p>处理器方法返回String表示视图完整路径</p>
    <form action="returnString-view2.do" method="post">
        姓名:<input type="text" name="name"><br/>
        年龄:<input type="text" name="age"><br/>
        <input type="submit" value="提交参数">
    </form>

(2)在MyController类中增加一个方法:

/**
     *处理器方法返回String--表示完整视图路径,此时不配置视图解析器(在springmvc.xml文件中)
     */
    @RequestMapping(value="/returnString-view2.do")
    public String doReturnView2(HttpServletRequest request,String name,Integer age){
        System.out.println("====doReturnView2====,name="+name+" age="+age);
        //2、如果还需要添加数据的话,可以手动添加数据到request作用域
        request.setAttribute("myname",name);
        request.setAttribute("myage",age);
        //完整视图路径,因为项目中不配置视图解析器
        //1、框架对视图执行forward转发操作,这样可以直接跳转到另一个页面了
        return "/WEB-INF/view/show.jsp";
    }

注意,将springmvc.xml中有关视图解析器的 (3)运行:
动力节点 SpringMVC P21-32_第7张图片
动力节点 SpringMVC P21-32_第8张图片

2.2 返回void

1、void:不能表示数据,也不能表示视图。在处理ajax的时候,可以使用void返回值。通过HttpServletResponse输出数据,响应ajax请求。ajax请求服务器端返回的就是数据,和视图无关。
2、代码编写
(1)复制项目,更名为ch04 return-void。ajax常用jquery实现请求的发起,我们先在webapp下新建js目录,随便找一个jquery的包放进去。
动力节点 SpringMVC P21-32_第9张图片
处理数据用的是json格式,因此需要在pom.xml文件中添加相关依赖。(如果后续写json出不来提示的话,可能idea还没加载完成,这时可以选中pom.xml文件,右键选择Maven,选择reimport):

    <!--Jackson依赖-->
    <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>

(2)在index.jsp中,首先要在头部将jquery库引入。然后为按钮绑定点击事件。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="js/jquery-2.2.3.min.js"></script>
    <script type="text/javascript">
        $(function () {
            $("button").click(function () {
                //alert("button click");
                $.ajax({
                    url:"returnVoid-ajax.do",
                    data:{
                        name:"zhangsan",
                        age:20
                    },
                    type:"post",
                    dataType:"json",
                    success:function (resp) {
                        //resp从服务器端返回的是json格式的字符串{"name":"zhangsan","age":20}
                        //jquery会把字符串转为json对象,赋给resp形参。
                        //alert(resp);//拿到resp后,会转成json object
                        alert(resp.name+"   "+resp.age);
                    }
                })
            })
        })
    </script>
</head>
<body>

    <p>处理器方法返回String表示视图名称</p>
    <form action="returnString-view.do" method="post">
        姓名:<input type="text" name="name"><br/>
        年龄:<input type="text" name="age"><br/>
        <input type="submit" value="提交参数">
    </form>
    <br/>
    <p>处理器方法返回String表示视图完整路径</p>
    <form action="returnString-view2.do" method="post">
        姓名:<input type="text" name="name"><br/>
        年龄:<input type="text" name="age"><br/>
        <input type="submit" value="提交参数">
    </form>
    <br/>
    <br/>
    <button id="btn">发起ajax请求</button>

</body>
</html>

(3)在MyController.class中:
如果写的过程中有红色波浪线,直接点击下面的Add exception…抛出异常即可。

@RequestMapping(value="/returnVoid-ajax.do")
    public void doReturnVoidAjax(HttpServletResponse response,String name,Integer age) throws IOException {
        System.out.println("====doReturnVoidAjax====,name="+name+" age="+age);
        //处理ajax,使用json做数据的格式
        //service调用完成了,使用student表示处理结果
        Student student = new Student();
        student.setName(name);
        student.setAge(age);

        String json = "";
        //把结果的对象转为json格式的数据
        if(student!=null){
            ObjectMapper om = new ObjectMapper();
            json = om.writeValueAsString(student);
            System.out.println("student转换的json====="+json);
        }

        //输出数据,响应ajax的请求
        response.setContentType("application/json;charset=utf-8");
        PrintWriter pw = response.getWriter();
        pw.println(json);//输出的json内容将传递给index.jsp中的ajax请求下的resp
        pw.flush();//刷新缓存
        pw.close();

    }
    

(4)运行:
动力节点 SpringMVC P21-32_第10张图片
动力节点 SpringMVC P21-32_第11张图片
动力节点 SpringMVC P21-32_第12张图片
(5) 观察发现,手工实现ajax,json数据时有重复的代码,比如当不仅有student对象,还有order对象,user对象等时,会有重复代码(2)(3)部分。如何使得(2)(3)部分由框架实现,程序员只要更加关注第(1)部分处理请求的业务逻辑处的代码,这时引入返回值object可以解决。

2.3 返回object

1、想要查找某个函数内部实现,比如HttpMessageConverter。在Idea中双击Shift键,输入HttpMessageConverter,按Enter键即可进入查看。
然后光标放在HttpMessageConverter上,按ctrl+H键,在右边能查看它的众多实现类分别有哪些。
动力节点 SpringMVC P21-32_第13张图片重点是勾出来的这两个类:
动力节点 SpringMVC P21-32_第14张图片

2.3.1 返回一个object对象

2、springmvc开发中,返回值是object类型,如何转换为 json ?

    实现步骤如下:
    1.加入处理json的工具库的依赖,springmvc默认使用的jackson。
    2.在springmvc配置文件中加入<mvc:annotation-driver>注解驱动。
        相当于实现原MyController中(2)的功能:
        json = om.writeValueAsString(student);
    3.在处理器方法上面加入@ResponseBody注解
        相当于实现原MyController中(3)的功能:
        response.setContentType("application/json;charset=utf-8");
        PrintWriter pw = response.getWriter();
        pw.println(json);

(1)加入处理json的工具库的依赖,springmvc默认使用的jackson。所以要在pom.xml文件中加入jackson依赖:

<!--jackson依赖-->
    <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>

(2)在springmvc配置文件中加入

 <!--添加注解驱动-->
    <mvc:annotation-driven />

注意:加这个注解的时候不要出现这个单词提示就按Enter,要看后面的提示是不是/mvc结尾,因为有好多同名的单词。选对了的话开头会出现这个:

xmlns:mvc="http://www.springframework.org/schema/mvc"
http://www.springframework.org/schema/mvc 
http://www.springframework.org/schema/tool/spring-mvc.xsd"

(3)在MyController类中写一下doStudentJsonObject()方法:

/**
     * 处理器方法返回一个Student,通过框架转为json,响应ajax请求
     * @ResponseBody:
     *      作用:把处理器方法返回对象转为json后,通过HttpServletResponse输出给浏览器。
     *      位置:方法的定义上面。和其他注解没有顺序关系。
     * @return
     */
    @RequestMapping(value="/returnStudentJson.do")
    @ResponseBody
    public Student doStudentJsonObject(String name, Integer age) {
        //调用service,获取请求结果数据,Student对象表示结果数据
        Student student = new Student();
        student.setName("李四同学");
        student.setAge(20);
        return student;//会被框架转为json
    }

(4)回到index.jsp,将前端ajax请求中的url换成returnStudentJson.do。
(5)运行:
动力节点 SpringMVC P21-32_第15张图片
动力节点 SpringMVC P21-32_第16张图片
动力节点 SpringMVC P21-32_第17张图片

2.3.2 返回多个object对象(也就是List数组)

1、在MyController类中增加一个处理器方法,返回Student列表对象。

/**
     * 处理器方法返回List
     */
    @RequestMapping(value="/returnStudentJsonArray.do")
    @ResponseBody
    public List<Student> doStudentJsonObjectArray(String name, Integer age) {

        List<Student> list = new ArrayList<>();
        //调用service,获取请求结果数据,Student对象表示结果数据
        Student student = new Student();
        student.setName("李四同学");
        student.setAge(20);
        list.add(student);

        student = new Student();
        student.setName("张三");
        student.setAge(28);
        list.add(student);

        return list;//会被框架转为json
    }

2、修改index.jsp处的ajax请求中的url地址和遍历list中的元素对象

$("button").click(function () {
                //alert("button click");
                $.ajax({
                    //url:"returnStudentJson.do",
                    url:"returnStudentJsonArray.do",
                    data:{
                        name:"zhangsan",
                        age:20
                    },
                    type:"post",
                    dataType:"json",
                    success:function (resp) {
                        //resp从服务器端返回的是json格式的字符串{"name":"zhangsan","age":20}
                        //jquery会把字符串转为json对象,赋给resp形参。

                        //[{"name":"李四同学","age":20},{"name":"张三","age":28}]
                        //alert(resp.name+"   "+resp.age);

                        $.each(resp,function (i,n) {
                            alert(n.name+"   "+n.age);
                        })
                    }
                })
            })

3、运行:
动力节点 SpringMVC P21-32_第18张图片
动力节点 SpringMVC P21-32_第19张图片
动力节点 SpringMVC P21-32_第20张图片
动力节点 SpringMVC P21-32_第21张图片

2.3.3 返回string(字符串)

1、在MyController类中增加一个处理器方法,返回String。

/**
     * 处理器方法返回String,String表示数据的,不是视图。
     * 区分返回值String是数据,还是视图,看有没有@ResponseBody注解
     * 如果有@ResponseBody注解,返回String就是数据,反之就是视图
     *
     * 默认使用“text/plain;charset=ISO-8859-1”作为contentType,导致中文有乱码,
     * 解决方案:给RequestMapping增加一个属性produces,使用这个属性指定新的contentType
     */
    @RequestMapping(value="/returnStringData.do",produces = "text/plain;charset=utf-8")
    @ResponseBody
    public String doStringData(String name, Integer age) {
        return "Hello SpringMVC 返回对象,表示数据";
    }

2、修改index.jsp处的ajax请求中的url地址;由于我们本身就是字符串数据,不需要切换成json数据,所以dataType类型改为text;弹窗弹出resp信息。

//(3) 返回string时
            $("button").click(function () {
                $.ajax({
                    url:"returnStringData.do",
                    data:{
                        name:"zhangsan",
                        age:20
                    },
                    type:"post",
                    dataType:"text",
                    success:function (resp) {
                        alert("返回的是文本数据:"+resp);
                    }
                })
            })

3、运行:
动力节点 SpringMVC P21-32_第22张图片
动力节点 SpringMVC P21-32_第23张图片

你可能感兴趣的:(springMVC,spring,mvc)