SpringMVC-快速入门(四)- Action返回值类型

SpringMVC-快速入门(四)- Action返回值类型,第1张

返回值有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";
}

运行结果:

2、返回值为void 2.1 方法名默认作为视图名

当方法没有返回值时,方法中并未指定视图的名称,则默认视图的名称为方法名

@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标签并未渲染成标题

3、返回值为ModelAndView

在旧的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;
}

运行结果:

5、返回值为Map

当返回结果为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,结果:

7.2 增加@ResponseBody修饰

如果在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;
    }
}

运行结果:

7.3 返回层级自定义类
@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 ,结果:

8、自定义输出内容 8.1 输出Excel

修改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 "
HelloExcel
"
; }

运行结果:

出现下载提升,打开文件:

  • 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 :

中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)

另外一种常见的媒体格式是上传文件之时使用的:
multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式

8.2 导出XLS时增加BOM头部解决乱码问题
//下载附件,导出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("");}

    str.append("
编号名称价格
"+car.getId()+""+car.getName()+""+car.getPrice()+"
"
); out.write(str.toString()); }
9、@ResponseBody

使用 @RequestMapping后,返回值通常解析为跳转路径,但是加上 @ResponseBody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body 中。

@ResponseBody 作用在方法上的,表示该方法的返回结果直接写入 HTTP response body中,@RequestBody 将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。

如果注解在控制器上面将作用与每一个方法上,每个方法都将受到影响。

10、@RestController

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;
    }
}
小结
  • 使用 String 作为请求处理方法的返回值类型是比较通用的方法,这样返回的逻辑视图名不会和请求 URL 绑定,具有很高的灵活性,而模型数据又可以通过Model控制。
  • 使用void、map、Model时,返回对应的逻辑视图名称真实url为:prefix前缀+控制器路径+方法名 +suffix后缀组成。
  • 使用String、ModelAndView返回视图名称可以不受请求的url绑定,ModelAndView可以设置返回的视图名称。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/787895.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-05
下一篇 2022-05-05

发表评论

登录后才能评论

评论列表(0条)

保存