返回值有String、void、基础类型、Model、ModelAndView、Map、自定义类、自定义输出内容、@ResponseBody修饰等。
默认如果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
如果方法声明了注解 @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是当前控制器映射的路径。
当方法的返回值为void,但输出流中存在输出内容时,则不会去查找视图,而是将输入流中的内容直接响应到客户端,响应的内容类型是纯文本。
@RequestMapping("/action8")
public void action8(HttpServletResponse response) throws IOException {
response.getWriter().write("not path,but content");
}
h2标签并未渲染成标题。
直接返回int、double、boolean等基本数据类型时会报错,需要使用注解 @ReponseBody。
@RequestMapping("/action38")
@ResponseBody
public int action38()
{
return 9527;
}
该接口Model定义在包org.springframework.ui下,model对象会用于页面渲染,视图路径使用 方法名,与void类似。
@RequestMapping("/action40")
public Model action40(Model model)
{
model.addAttribute("message", "返回类型为org.springframework.ui.Model");
return model;
}
在旧的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;
}
当返回结果为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相当于模型,在视图中可以取出。
当返回值为自定义类型时,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
";
}
Response.AppendHeader("Content-Disposition","attachment;filename=FileName.txt");
常见的媒体格式类型如下:
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 :
另外一种常见的媒体格式是上传文件之时使用的:
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());
}
使用 @RequestMapping后,返回值通常解析为跳转路径,但是加上 @ResponseBody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body 中。
@ResponseBody 作用在方法上的,表示该方法的返回结果直接写入 HTTP response body中,@RequestBody 将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。
如果注解在控制器上,将作用于控制器内的每一个方法上,每个方法都将受到影响。
Spring 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;
}
}