返回值有String、void、Model、ModelAndView、Map、自定义类、基础类型、自定义输出内容、@ResponseBody修饰等
1、返回值为String 1.1 String作为视图名称默认如果action返回String,此时的String为视图名称,会去视图解析器的设定的目录下查找。查找的规则是:URL = prefix前缀+视图名称+suffix后缀组成。
@RequestMapping("/action31")
public String action31(Model model)
{
model.addAttribute("message","action31");
return "bar/action31";
}
Spring MVC的配置文件内容如下:
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
bean>
实际url=/WEB-INF/views/bar/action31.jsp
1.2 String作为内容输出如果方法声明了注解@ResponseBody ,将内容或对象作为 HTTP 响应正文返回,并调用适合HttpMessageConverter的Adapter转换对象,写入输出流。此时的String不再是路径而是内容。
@RequestMapping("/action7")
@ResponseBody
public String action7(){
return "not path,but content";
}
运行结果:
当方法没有返回值时,方法中并未指定视图的名称,则默认视图的名称为方法名。
@RequestMapping("/action33")
public void action33()
{
}
会去访问的路径是:url=/WEB-INF/views/bar/action33.jsp,bar是当前控制器映射的路径。
2.2 直接响应输出结果当方法的返回值为void,但输出流中存在输出内容时,则不会去查找视图,而是将输入流中的内容直接响应到客户端,响应的内容类型是纯文本。
@RequestMapping("/action8")
public void action8(HttpServletResponse response) throws IOException {
response.getWriter().write("not path,but content");
}
运行结果:
h2标签并未渲染成标题
在旧的Spring MVC中ModelAndView使用频率非常高,它可以同时指定返回的模型与视图对象或名称。
@RequestMapping("/action35")
public ModelAndView action35()
{
//1只指定视图
//return new ModelAndView("/bar/index");
//2分别指定视图与模型
//Map model=new HashMap();
//model.put("message", "ModelAndView action35");
//return new ModelAndView("/bar/index",model);
//3同时指定视图与模型
//return new ModelAndView("/bar/index","message","action35 ModelAndView ");
//4分开指定视图与模型
ModelAndView modelAndView=new ModelAndView();
//指定视图名称
modelAndView.setViewName("/bar/index");
//添加模型中的对象
modelAndView.addObject("message", "Hello ModelAndView");
return modelAndView;
}
4、返回值为Model类型
该接口Model定义在包org.springframework.ui下,model对象会用于页面渲染,视图路径使用方法名,与void类似。
@RequestMapping("/action40")
public Model action40(Model model)
{
model.addAttribute("message", "返回类型为org.springframework.ui.Model");
return model;
}
运行结果:
当返回结果为Map时,相当于只是返回了Model,并未指定具体的视图,返回视图的办法与void是一样的,即URL= prefix前缀+控制器路径+方法名称 +suffix后缀组成
@RequestMapping("/action36")
public Map<String, Object> action36()
{
Map<String, Object> model=new HashMap<String,Object>();
model.put("message", "Hello Map");
model.put("other", "more item");
return model;
}
实际访问的路径是:/SpringMVC03/WEB-INF/views/bar/action36.jsp,返回给客户端的map相当于模型,在视图中可以取出。
6、返回值为任意类型直接返回int、double、boolean等基本数据类型时会报错,需要使用注解@ReponseBody。
@RequestMapping("/action38")
@ResponseBody
public int action38()
{
return 9527;
}
7、返回值为自定义类型
7.1 直接返回自定义类
当返回值为自定义类型时,Spring会把方法认为是视图名称,与返回值为void的类似办法处理URL= prefix前缀+控制器路径+方法名称 +suffix后缀组成。
@Controller
@RequestMapping("/param")
public class ParamController {
@RequestMapping("/action9")
public Product action9(){
Product product = new Product(1001,"lili",1.2f);
return product;
}
}
增加/WEB-INF/view/param/action9.jsp
action9.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
产品名称: ${product.name}<br>
产品价格: ${product.price}
访问地址 http://localhost:8080/param/action9,结果:
如果在action上添加@ResponseBody注解则返回的是Product本身,而非视图,Spring会选择一个合适的方式解析对象,默认是json。
@Controller
@RequestMapping("/param")
public class ParamController {
@RequestMapping("/action9")
@ResponseBody
public Product action9(){
Product product = new Product(1001,"lili",1.2f);
return product;
}
}
运行结果:
@Controller
@RequestMapping("/param")
public class ParamController {
@RequestMapping("/action10")
@ResponseBody
public Factory action10(){
ArrayList<Product> products = new ArrayList<>();
Product product1 = new Product(1001,"lili",1.2f);
Product product2 = new Product(1002,"lucy",1.3f);
products.add(product1);
products.add(product2);
Factory factory = new Factory("factory1", products);
return factory;
}
}
运行 http://localhost:8080/param/action10 ,结果:
修改http的头部信息,实现如下载Excel、Pdf文档。
@RequestMapping("/action41")
@ResponseBody
public String action41(HttpServletResponse response)
{
response.setHeader("Content-type","application/octet-stream");
response.setHeader("Content-Disposition","attachment; filename=table.xls");
return "Hello Excel
";
}
运行结果:
出现下载提升,打开文件:
- Content-disposition解释:
Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。当 Internet Explorer 接收到头时,它会激活文件下载对话框,它的文件名框自动填充了头中指定的文件名。
服务端向客户端游览器发送文件时,如果是浏览器支持的文件类型,一般会默认使用浏览器打开,比如txt、jpg等,会直接在浏览器中显示,如果需要提示用户保存,就要利用Content-Disposition进行一下处理,关键在于一定要加上attachment:
Response.AppendHeader("Content-Disposition","attachment;filename=FileName.txt");
- Content-Type解释:
MediaType,即是Internet Media Type,互联网媒体类型;也叫做MIME类型,在Http协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息。
常见的媒体格式类型如下:
text/html : HTML格式
text/plain :纯文本格式
text/xml : XML格式
image/gif :gif图片格式
image/jpeg :jpg图片格式
image/png:png图片格式
以application开头的媒体格式类型:
application/xhtml+xml :XHTML格式
application/xml : XML数据格式
application/atom+xml :Atom XML聚合格式
application/json : JSON数据格式
application/pdf :pdf格式
application/msword : Word文档格式
application/octet-stream : 二进制流数据(如常见的文件下载)
application/x-www-form-urlencoded :
8.2 导出XLS时增加BOM头部解决乱码问题另外一种常见的媒体格式是上传文件之时使用的:
multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式
//下载附件,导出Excel,xls
@RequestMapping("/act21")
@ResponseBody
public void act21(HttpServletResponse response) throws IOException {
//解决:严格来说这并不是xls文件的问题,而是Excel处理文件编码方式问题,Excel默认并不是以UTF-8来打开文件,所以在xls开头加入BOM,告诉Excel文件使用utf-8的编码方式。
response.setHeader("Content-Type","application/octet-stream;charset=utf-8");
response.setHeader("Content-Disposition","attachment;filename=Cars.xls");
PrintWriter out = response.getWriter();
//加上bom头,解决excel打开乱码问题
byte[] bomStrByteArr = new byte[] { (byte) 0xef, (byte) 0xbb, (byte) 0xbf };
String bomStr = new String(bomStrByteArr, "UTF-8");
out.write(bomStr);
StringBuffer str=new StringBuffer("");
str.append("");
str.append("编号 名称 价格 ");
for (Car car: Car.cars) {
str.append(""+car.getId()+" "+car.getName()+" "+car.getPrice()+" ");
}
str.append("
");
out.write(str.toString());
}
9、@ResponseBody
使用 @RequestMapping后,返回值通常解析为跳转路径,但是加上 @ResponseBody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body 中。
@ResponseBody 作用在方法上的,表示该方法的返回结果直接写入 HTTP response body中,@RequestBody 将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。
如果注解在控制器上面将作用与每一个方法上,每个方法都将受到影响。
10、@RestControllerSpring 4 MVC中提供的@RestController,使用最少的代码来构建一个Restful Web Service,支持返回xml或json数据,这个可以让用户选择,通过URL后缀.xml或.json来完成。
@RestController是继承自@Controller与@ResponseBody的,所以它同时拥有他们的特性。
REST即表述性状态传递(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。它是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。
目前在三种主流的Web服务实现方案中,因为REST模式的Web服务与复杂的SOAP和XML-RPC对比来讲明显的更加简洁,越来越多的web服务开始采用REST风格设计和实现。例如,Amazon.com提供接近REST风格的Web服务进行图书查找;雅虎提供的Web服务也是REST风格的。
Rest风格的URL:
新增: http://www.zhangguo.com/order POST
修改: http://www.zhangguo.com/order/1 PUT update?id=1
获取:http://www.zhangguo.com/order/1 GET get?id=1
删除: http://www.zhangguo.com/order/1 DELETE delete?id=1
实现方法一:
返回
比如异步获取 json 数据,加上 @ResponseBody 后,会直接返回 json 数据。
新增: http://www.zhangguo.com/order POST
修改: http://www.zhangguo.com/order/1 PUT update?id=1
获取:http://www.zhangguo.com/order/1 GET get?id=1
删除: http://www.zhangguo.com/order/1 DELETE delete?id=1
package com.zhangguo.springmvc01.controller;
import com.zhangguo.springmvc01.entities.Car;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/car")
public class CarController {
/**
* post新增
* url: http://localhost:8080/car
* @return
*/
@PostMapping
public Car addCar(Car car){
return car;
}
/**
* put请求
* url: http://localhost:8080/car/12
* @param id
* 修改参数
* @return
*/
@PutMapping("/{id}")
public Car updateCar(@PathVariable int id){
return car;
}
/**
* get请求
* url: http://localhost:8080/car/12
* @param id
* 查询的参数
* @return
*/
@GetMapping("/{id}")
public Car getCar(@PathVariable int id){
return car;
}
/**
* delete请求
* url: http://localhost:8080/car/12
* @param id
* 查询的参数
* @return
*/
@DeleteMapping("/{id}")
public Car deleteCar(@PathVariable int id){
return car;
}
}
小结
- 使用 String 作为请求处理方法的返回值类型是比较通用的方法,这样返回的逻辑视图名不会和请求 URL 绑定,具有很高的灵活性,而模型数据又可以通过Model控制。
- 使用void、map、Model时,返回对应的逻辑视图名称真实url为:prefix前缀+控制器路径+方法名 +suffix后缀组成。
- 使用String、ModelAndView返回视图名称可以不受请求的url绑定,ModelAndView可以设置返回的视图名称。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)