关于响应数据的简单介绍
在SpringMVC中,数据的响应有两种方式,一种是显示页面的页面跳转,另一种是显示数据的数据写回.我们会 介绍如何进行这两种方式的响应数据,以及如何在相应的时候添加参数.
页面跳转
关于页面跳转,我们在之前的案例中已经有过一些接触了,最直观的体现就是在我们的控制器类中的控制器方法的返回值 的地方,返回值的类型可以为空,字符串,以及我们之前没有见过的ModelAndView,我们主要对这三种返回值对应 跳转的页面做简单介绍.
首先是当方法的返回值是空的时候
当方法的返回值为空的时候,会跳转到方法的默认页面,这个默认页面是如何生成的呢?是通过我们在页面解析器 中配置的前缀+方法名+后缀,拼接成一个完整的页面路径,在我们访问控制器类方法的映射路径的时候,就会根据这个 规则自动生成一个默认页面进行相应,如果找不到这个页面,就会在浏览器中报错,返回500服务器出错.
Java代码:
@RequestMapping("/index")
public void index(){
System.out.println("放访问的处理器方法的返回值是空的时候");
}
运行结果:
当我们正常的访问控制器方法的请求路径的时候,我们可以看一下它最终请求的页面
这个页面就是我们之前编写的页面,那么这个页面是怎么得到的呢?
页面路径拼接图示:
当访问的资源不存在的时候:
这次我们访问另一个控制器类方法,这个方法没有默认的响应页面:
显示请求的资源不存在,我们主要去关注它请求资源的路径,这里就非常清楚的显示出我们请求的是哪一个资源。
然后是方法的返回值是字符串的时候
这种方法是我们最常用的一种情况,因为他跳转的页面就是页面解析器的前缀+返回值+后缀组成的一个完整的 页面路径,也就是说,只要方法的返回值保持一致,我们相应的页面就是同一个.
Java代码:
@RequestMapping("/HttpCarryDate")
public String HttpCarryDate(String name , HttpServletRequest request){
request.setAttribute("name",name);
return "CarryData";
}
请求成功的显示:
当我们请求成功之后,我们就可以很顺利地看到相应的页面,并且这个页面的名字就是我们返回值的名字
请求失败的显示:
这里请求失败了,请求的文件名就是方法的返回值,此处这个返回值对应的页面文件并不存在,所以此处请求不到资源
返回值是ModelAndView类型的时候
这种类型是一种同时封装了数据和页面的数据类型.ModelAndView对象包含视图相关内容和模型数据两个部分.其中 视图相关的内容可以设置逻辑视图的名称,也可以设置具体的View实例,模型数据则会在视图渲染过程中被合并到最终的 视图输出. 在我们使用的时候,主要会应用到两个方法,一个是用来设置视图的时候,需要使用到setViewName(String ViewName) 以及用来添加数据的addObject(String 数据名,Object 数据),然后在页面中就可以使用EL语法获取到我们传递的数据 虽然这个类我们第一次见,但是它的底层使用的依然是我们之前学习过的作用域的方法.
Java代码:
@RequestMapping("/ModelAndViewCarryData")
public ModelAndView ModelAndViewCarryData(String name, ModelAndView m){
m.addObject("name",name);
m.setViewName("CarryData");
return m;
}
HTML代码:
<form action="${pageContext.request.contextPath}/ModelAndViewCarryData">
<p>请输入你的名字:</p>
<input type="text" name="name">
<input type="submit" value="提交">
</form>
<h1>欢迎你:${name}</h1>
<hr>
当我们在页面中输入名字并提交之后,我们可以在同一个页面看到我们刚才提交的数据,这就是非常方便的将数据传递到页面中。
除了使用ModelAndView,还可以使用其他方式向页面中传递数据
这个方式是通用的,当我们在响应页面的时候,如果有一个需要向页面中携带数据的需求,那么我们就可以 在方法的形参处添加一个HttpServletRequest类型的参数,或者一个Model类型的参数,通过这两个类的 addAttribute(String 参数名,String 参数值);的方式,我们可以向Request域中传递我们的参数,并且可以在 页面中使用EL表达式获取到我们传入的值.
Java代码:
@RequestMapping("/HttpCarryDate")
public String HttpCarryDate(String name , HttpServletRequest request){
request.setAttribute("name",name);
return "CarryData";
}
HTML代码:
<h1>测试HttpServletRequest的方式携带数据</h1>
<form action="${pageContext.request.contextPath}/HttpCarryDate">
<p>请输入你的名字:</p>
<input type="text" name="name">
<input type="submit" value="提交">
</form>
<h1>欢迎你:${name}</h1>
<hr>
注意点
其实响应页面的方法非常的简单,只需要配置好我们的页面解析器,然后根据返回值的类型控制我们响应何种页面即可
数据回写
有时客户端希望服务器在响应时不要进行页面跳转,只需要回写相关的数据即可.这时候我们就可以选择在响应时直接将 数据写入输出流中,而不经过视图解析器. 可以将会写到输出流的数据分为普通字符串和JSON数据
回写普通数据
以数据回写的方式响应时,可以使用SpringMVC默认支持的类型完成数据的输出.即通过HttpServletResponse类来 将普通的字符串响应到页面中 首先我们需要在控制器类的控制器方法的形参中添加一个HTTPServletResponse对象,然后通过这个对象的getWriter方法 调用print(String 字符串)的方式将字符串响应到页面中. 这里需要注意,这个方法是没有返回值的,之前我们说过,没有返回值的方法,默认返回的页面是由页面解析器的 前缀+方法名+后缀来响应默认的页面的,但是当我们配置了响应体,也就是刚才我们通过HTTPServletResponse调用 的方法输出了一个字符串.当我们进行了这样的配置之后,这个控制器就会执行响应体中的数据回写,而不是响应 默认的界面.
Java代码:
// 测试简单数据的数据回写
@RequestMapping("/ResponseDate")
public void ResponseDate(HttpServletResponse response){
try {
response.getWriter().println("response");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
运行结果:
数据回写的显示不需要页面,所以我们直接访问控制器类的路径就可以显示数据
回写JSON数据
在数据会写中,我们更多的是回写JSON数据,可以将对象,集合,数据等信息转换成JSON中,回写到浏览器中 而将java中的对象转换成JSON数据的方式也非常的简单,我们使用之前用过的jackson,可以直接将Java中 的对象转换成字符串,然后通过HttpServletResponse对象将字符串相应出去,就可以直接在浏览器的界面上 显示JSON格式的数据.
Java类:
// 测试回写JSON格式的数据
@RequestMapping("/ResponseJson")
public void ResponseJson(HttpServletResponse response) throws IOException {
ArrayList<User> users = new ArrayList<>();
User u1 = new User();
u1.setId(1);
u1.setUsername("张三");
User u2 = new User();
u2.setId(2);
u2.setUsername("李四");
User u3 = new User();
u3.setId(3);
u3.setUsername("王五");
users.add(u1);
users.add(u2);
users.add(u3);
// 通过调用一个特殊的方法的方式将Java类转换成JSON格式的字符串进行响应
ObjectMapper om = new ObjectMapper();
String s = om.writeValueAsString(users);
response.getWriter().println(s);
System.out.println(users.toString());
}
运行结果:
可以看到,当数据回写涉及到中文的时候,就会很大概率出现乱码的情况,我们在后面使用注解的时候就可以避免这个问题,而我们使用最多的也是使用注解的情况
通过ResponseBody注解来将方法的数据回写变成JSON类型的
之前我们也接触过这个注解,当时我们使用这个注释是因为我们需要将前端传递进来的参数转换成Java类进行操作 当时这个注解是写在了控制器方法的形参前面,将传递进来的JSON参数转换成我们的Java类进行操作. 但是这次我们要写在其他的地方,当这个注解写在方法上时,表示这个方法的返回值类型将以数据回写的方式响应 JSON格式的数据到浏览器中,无论这个方法的返回值是什么,都会将他转换成JSON格式的数据进行数据回写. 所以我们只要在类中加上了这个注解,我们方法的返回值可以随意写,无论是返回对象,数据,集合还是字符串 最后都会变成JSON数据响应到浏览器中
Java代码:
// 测试使用注解回写JSON格式的数据
@ResponseBody
@RequestMapping("/ResponseRespinseBodyJson")
public ArrayList ResponseRespinseBodyJson(HttpServletResponse response) throws IOException {
ArrayList<User> users = new ArrayList<>();
User u1 = new User();
u1.setId(1);
u1.setUsername("张三");
User u2 = new User();
u2.setId(2);
u2.setUsername("李四");
User u3 = new User();
u3.setId(3);
u3.setUsername("王五");
users.add(u1);
users.add(u2);
users.add(u3);
return users;
}
运行结果: