哔哩哔哩参考链接
笔记参考链接
当形参过多时,仍使用逐个接收参数的方式非常繁琐,这里介绍对象接收参数的方式。
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。
(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>
处理器方法的返回值分为四种:返回ModelAndView(适合既需要数据又需要视图的情况,视图需要forward转发)、返回String、返回void、返回对象Object
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运行:
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中有关视图解析器的
1、void:不能表示数据,也不能表示视图。在处理ajax的时候,可以使用void返回值。通过HttpServletResponse输出数据,响应ajax请求。ajax请求服务器端返回的就是数据,和视图无关。
2、代码编写
(1)复制项目,更名为ch04 return-void。ajax常用jquery实现请求的发起,我们先在webapp下新建js目录,随便找一个jquery的包放进去。
处理数据用的是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)运行:
(5) 观察发现,手工实现ajax,json数据时有重复的代码,比如当不仅有student对象,还有order对象,user对象等时,会有重复代码(2)(3)部分。如何使得(2)(3)部分由框架实现,程序员只要更加关注第(1)部分处理请求的业务逻辑处的代码,这时引入返回值object可以解决。
1、想要查找某个函数内部实现,比如HttpMessageConverter。在Idea中双击Shift键,输入HttpMessageConverter,按Enter键即可进入查看。
然后光标放在HttpMessageConverter上,按ctrl+H键,在右边能查看它的众多实现类分别有哪些。
重点是勾出来的这两个类:
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配置文件中加入 注意:加这个注解的时候不要出现这个单词提示就按Enter,要看后面的提示是不是/mvc结尾,因为有好多同名的单词。选对了的话开头会出现这个: (3)在MyController类中写一下doStudentJsonObject()方法: (4)回到index.jsp,将前端ajax请求中的url换成returnStudentJson.do。 1、在MyController类中增加一个处理器方法,返回Student列表对象。 2、修改index.jsp处的ajax请求中的url地址和遍历list中的元素对象 1、在MyController类中增加一个处理器方法,返回String。 2、修改index.jsp处的ajax请求中的url地址;由于我们本身就是字符串数据,不需要切换成json数据,所以dataType类型改为text;弹窗弹出resp信息。 <!--添加注解驱动-->
<mvc:annotation-driven />
xmlns:mvc="http://www.springframework.org/schema/mvc"
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/tool/spring-mvc.xsd"
/**
* 处理器方法返回一个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
}
(5)运行:
2.3.2 返回多个object对象(也就是List数组)
/**
* 处理器方法返回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);
})
}
})
})
2.3.3 返回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 返回对象,表示数据";
}
//(3) 返回string时
$("button").click(function () {
$.ajax({
url:"returnStringData.do",
data:{
name:"zhangsan",
age:20
},
type:"post",
dataType:"text",
success:function (resp) {
alert("返回的是文本数据:"+resp);
}
})
})