JavaWeb框架-SpringMVC-4-文件上传与返回JSON数据

来源:互联网 发布:淘宝哪里找分销 编辑:程序博客网 时间:2024/06/04 00:51

话说

各位读者盆友,下午好!有几天都没见面了,甚是想念大家。这几天笔者没有发表博客,主要还是没有进入状态,一旦进入状态,就好了。

今天的博客也比较简短,分享下SpringMVC的文件上传(单文件、多文件)及返回JSON数据,与页面交互。

目录


1、项目整体架构
2、文件上传
3、返回JSON数据
4、总结


开发环境:IntelliJ IDEA(2017.2.5)
Maven Web项目

1、项目整体架构

这里写图片描述

2、文件上传

文件上传流程都是差不多:导包==》增加文件域==》配置文件上传处理器==》调用FileUtils来写方法

1)单文件上传

1、导包导入fileUpload这个包
    <!--支持文件上传-->    <dependency>      <groupId>commons-fileupload</groupId>      <artifactId>commons-fileupload</artifactId>      <version>1.3.3</version>    </dependency>

2、修改表单。

增加文件域、增加enctype属性。我们之前写了springMVC的增删改查,在增的基础上,增加以下图片。

在add.jsp中增加:

 <td>    <input type="file" name="bookCover"></td>

同时,修改表单:

<form action="add.htm" method="post" enctype="multipart/form-data">

这里就是增加一个enctype属性,表明告诉表单,表单你好,我要上传文件啦,你要能够自动处理这种格式奥!

3、配置文件上传处理器

 <!--配置文件上传处理器-->    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>    <!--上面的id必须要叫这个名字:multipartResolver-->

4、对应的Controller层对应的方法中添加MultipartFile参数

 /**     * 执行新增图书     */    @RequestMapping(value = "add.htm",method = RequestMethod.POST)    public String add(Book book, @RequestParam("bookCover") MultipartFile bookCover) throws IOException {        /*System.out.println("getName== "+bookCover.getName());        System.out.println("getContextType===   "+bookCover.getContentType());        System.out.println("getOriginalFilename==   "+bookCover.getOriginalFilename());        System.out.println("getInputStream  ===  "+bookCover.getInputStream());*/            FileOutputStream fos = new FileOutputStream("F:\\"+bookCover.getOriginalFilename());            FileCopyUtils.copy(bookCover.getInputStream(),fos);            book.setCover(bookCover.getOriginalFilename());//这里需要手动赋值       // FileUtils.copyFile(cover,fos); //用不了 没法给一个file        books.put(book.getId(),book);        return "redirect:list.htm";    }

这里其他注释代码都是为了了解MultipartFile的其他属性,真正核心代码就2行:


 FileOutputStream fos = new FileOutputStream("F:\\"+bookCover.getOriginalFilename());            FileCopyUtils.copy(bookCover.getInputStream(),fos);

文件上传本质就是复制粘贴,复制粘贴本质就是流。搞定输入输出流,就搞定了文件上传。不过人家内部怎么实现的,还是蛮神奇的。

这里我们用的是: FileCopyUtils.copy(inputStream in,outputStream out)而没有用:FileUtils.copyFile(File input ,OutputStream out),是因为没法传入File这个参数呢。所以用FileCopyUtiles.copy()简单些,2种流可以直接获取。这就是变通喽。

2)多文件上传

多文件上传就是转换成数组,遍历一下即可。
页面上增加多个文本域。

<tr>               <td>                   <input type="file" name="bookCover"/>               </td>               <td>                   <input type="file" name="bookCover">               </td>               <td>                   <input type="file" name="bookCover">               </td>           </tr>

修改代码如下:

 /**     * 执行新增图书     */    @RequestMapping(value = "add.htm",method = RequestMethod.POST)    public String add(Book book, @RequestParam("bookCover") MultipartFile bookCover[]) throws IOException {        /*System.out.println("getName== "+bookCover.getName());        System.out.println("getContextType===   "+bookCover.getContentType());        System.out.println("getOriginalFilename==   "+bookCover.getOriginalFilename());        System.out.println("getInputStream  ===  "+bookCover.getInputStream());*/        for(int i=0;i<bookCover.length;i++) {            FileOutputStream fos = new FileOutputStream("F:\\"+bookCover[i].getOriginalFilename());            FileCopyUtils.copy(bookCover[i].getInputStream(),fos);        }          //  book.setCover(bookCover.getOriginalFilename());//这里需要手动赋值       // FileUtils.copyFile(cover,fos); //用不了 没法给一个file        books.put(book.getId(),book);        return "redirect:list.htm";    }

这里变化点就是把MultipartFile bookCover变成了数组而已,然后遍历取值。

特别注意!

因为springMVC特殊的传参方式,所以实体类的属性名和表单中的name默认一致,文本域的name属性不要和实体类的属性一致,假如实体类有个属性叫String cover,你的文本域的name也叫cover,那么当你提交表单时候,框架就会默认给实体类的cover属性赋值,但是因为你的cover是MultipartFile类型,就会报错:400或者500!那时候,就比较悲剧,你左看右看,上看下看,怎么看代码都没问题!

所以,框架中,起名字是有讲究的,不要任性,也不要偷懒。取不一样的名字就好。这里用的就是bookCover。

3、返回JSON数据

SpringMVC中提供了与前端的交互方式——返回JSON数据。前端可以直接用Ajax获取值,灰常方便奥。

怎么做列?还是老套路:导包==》写方法加注解。核心就是ResponseBody这个注解。

我们要实现什么效果呢?就是类似的这样一个效果,页面访问的时候,直接返回JSON格式的数据。

这里写图片描述

1)导包
2)写方法

1)导包

非常简单,只用导入databind这个包,其他2个包都会自动导入。

    <!--Spring mvc 支持返回json数据-->    <dependency>      <groupId>com.fasterxml.jackson.core</groupId>      <artifactId>jackson-databind</artifactId>      <version>2.9.2</version>    </dependency>

最终应该有3个包:jackson-databind、jackson-annotations、jackson-core

2)写方法

 /**     * 返回JSON数据     */    @RequestMapping("jsonList.htm")    @ResponseBody    public Map<String,Object> list() {        Map<String,Object> datas = new HashMap<String,Object>();        datas.put("total",28);        List<Book> books = new ArrayList<Book>();        Book book1 = new Book(1,"《神雕侠侣》");        Book book2 = new Book(2,"《封神演义》");        Book book3 = new Book(3,"《八仙过海》");        books.add(book1);        books.add(book2);        books.add(book3);        datas.put("rows",books);        return datas;    }    /**     * 以上方法会报错:     * HTTP Status 500 - No converter found for return value of type: class java.util.HashMap     * 暂且搁置:换一种方法,直接用类来     */

要实现的效果是:页面访问jsonList.htm的时候,直接出现我们示例那张图的样式。
然鹅,实际效果确实这样:

这里写图片描述

网上查了资料,说是需要在springmvc-servlet.xml中加这样的配置:

 <!-- rest json related... start -->    <bean id="mappingJacksonHttpMessageConverter"          class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">        <property name="supportedMediaTypes">            <list>                <value>application/json;charset=UTF-8</value>            </list>        </property>    </bean>    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">        <property name="messageConverters">            <list>                <ref bean="mappingJacksonHttpMessageConverter"/>            </list>        </property>    </bean>-->

在下加了,找不到这个包,暂且搁置。换一种方法,我们写一个类,然后重新输出一下:
Pager类如下:

package com.hmc.springmvc.model;import java.util.List;/** * User:Meice * 2017/11/18 */public class Pager {    private int total;    private List<Book> rows;    public int getTotal() {        return total;    }    public void setTotal(int total) {        this.total = total;    }    public List<Book> getRows() {        return rows;    }    public void setRows(List<Book> rows) {        this.rows = rows;    }}

方法如下:

 @RequestMapping("jsonlist.htm")    @ResponseBody    public Pager list2() {        Pager pager = new Pager();        pager.setTotal(28);        List<Book> books = new ArrayList<Book>();        Book book1 = new Book(1,"《神雕侠侣》");        Book book2 = new Book(2,"《封神演义》");        Book book3 = new Book(3,"《八仙过海》");        books.add(book1);        books.add(book2);        books.add(book3);        pager.setRows(books);        return pager;    }

这样还是没搞定,暂且搁置。整体思路就是这样的,是以记之,后续有更好方式在做修改。

4、总结


1、文件上传:导入fileUpload这个包,表单增加属性enctype=“multipart/form-data”,在springmvc-servlet.xml中配置文件上传处理器:CommonsMultipartResolver,采用FileUtils或者FileCopyUtils的copyFile方法即可。本质就是输入流、输出流;

2、返回JSON数据是为了更好的和前端进行交互。核心就是注解@ResponseBody。这个案例中有Bug,后续再深度清理。


好了,下期再会!下期,我们将回顾MyBatis啦。

原创粉丝点击