商家后台-商品录入【商品图片上传】

1.1 需求分析

在商品录入界面实现多图片上传

商家后台-商品录入【商品图片上传】

当用户点击新建按钮,弹出上传窗口

商家后台-商品录入【商品图片上传】

  • 实现思路分析:
  1. AngularJS图片上传(异步请求上传图片)。
  2. SpringMVC图片上传(配置文件上传依赖jar包、配置文件上传解析器、控制器接收上传的文件)
  3. FastDFS图片文件器(配置客户端依赖jar包、配置文件、编写上传服务器代码)
  • 商品图片上传:

   -- 需求分析
      Angularjs图片上传(异步请求上传图片)
      -- 异步请求代码
            /** 文件上传方法 */
        this.uploadFile = function(){
        /** 创建表单对象 */
        var formData = new FormData(); // html5 FormData
        /** 追加需要上传的文件 */
        formData.append("file", file.files[0]);
        /** 发送异步请求上传文件 */
        return $http({
            method : 'post', // 请求方式
            url : "/upload", // 请求URL
            data : formData, // 表单数据
            headers : {'Content-Type' : undefined}, // 请求头
            transformRequest : angular.identity  // 转换对象
        });
        };

    SpringMVC接收上传的文件(配置文件上传依赖jar、
             配置文件上传解析器、控制器接收上传的文件)
     
    FastDFS图片服务器(配置客户端依赖jar、
             配置文件、编写上传服务器代码)

      注意:开启图片服务器

1.2 图片上传

 1.2.1 上传服务

sunny-shop-web/src/main/webapp/js/controller/baseService.js中的uploadFile()方法:

app.service("baseService", function($http){

......
   
/** 文件上传方法 */
   
this.uploadFile = function(){
       
/** 创建表单对象 */
      
 
var formData = new FormData();
        /** 追加需要上传的文件 */
      
 
formData.append("file", file.files[0]);
        /** 发送异步请求上传文件 */
       
return $http({
           
method : 'post', // 请求方式
           
url : "/upload", // 请求URL
          
 
data : formData, // 表单数据
           
headers : {'Content-Type' : undefined}, // 请求头
           
transformRequest : angular.identity  // 转换对象
       
});
    };
});

  • angularJS对于post和get请求默认的Context-Type header是application/json。通过设置‘Content-Type’: undefined,这样浏览器会帮我们把Content-Type设置为 multipart/form-data.
  • 设置 transformRequest : angular.identity,angularjs transformRequest function 将序列化表单对象中的文件为二进制数据. 

  1.2.2 前端代码

goods_edit.html,修改图片上传窗口,调用上传方法,回显上传图片(300行左右)

<table class="table table-bordered table-striped">
   <
tr>
      <
td>颜色</td>
      <
td><input class="form-control"
              
ng-model="picEntity.color" placeholder="颜色"
></td>
   </
tr>
   <
tr>
      <
td>商品图片</td>
      <
td>
         <
table>
            <
tr>
               <
td><input type="file" id="file"/>
                  <
button class="btn btn-primary"
                       
ng-click="uploadFile()"
                        type="button"
>上传</button>
               </
td>
               <
td><img src="{{picEntity.url}}"
                      width="200px" height="200px"
></td>
            </
tr>
         </
table>
      </
td>
   </
tr>
</
table>

sunny-shop-web/src/main/webapp/js/controller/goodsController.js中编写代码 

/**上传图片 */
$scope.uploadFile = function(){
   baseService.
uploadFile().then(function(response) {
     
/** 如果上传成功,取出url */
     
if(response.data.status == 200){
       
 /** 设置图片访问地址 */
        
$scope.picEntity.url = response.data.url;
      }else{
         alert(
"上传失败!");
      }
   });
};

goods_edit.html修改新建按钮,绑定点击事件(122),用于初始化对象(清空数据)

<div class="btn-group">
   <
button type="button" class="btn btn-default" title="新建"
        
data-target="#uploadModal" data-toggle="modal"
        
ng-click="picEntity={}"
>
      <
i class="fa fa-file-o"></i> 新建
  
</button>
</
div> 

1.3 后端代码

1.3.1 配置依赖

sunny-shop-web/pom.xml,配置引入依赖

<!-- commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
</dependency>
<!-- fastdfs-client -->
<dependency>
    <groupId>org.csource</groupId>
    <artifactId>fastdfs-client</artifactId>
</dependency>

 1.3.2 配置文件上传解析器

sunny-shop-web/src/main/resources/springmvc.xml配置文件上传解析器

<!-- 配置文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
   
<!-- 设置文件上传默认编码 -->
   
<property name="defaultEncoding" value="UTF-8"/>
   
<!-- 设置文件上传大小 2MB: 2*1024*1024 -->
   
<property name="maxUploadSize" value="2097152"/>
</
bean>

1.3.3 控制器层、fastdfs_client.conf配置文件、application.properties配置文件

(1)在sunny-shop-web/src/main/resources目录下创建fastdfs_client.conf

商家后台-商品录入【商品图片上传】

(2) 在sunny-shop-web/src/main/resources/目录下,新建application.properties,并添加属性

商家后台-商品录入【商品图片上传】

(3)在sunny-shop-web/src/main/resources/springmvc.xml配置加载application.properties

<!-- 加载属性文件 -->
<context:property-placeholder location="classpath:application.properties"/>

 控制器层:在sunny-shop-web/src/main/java/com.sunny.shop.controller包下创建UploadController.java

  • 这时需要思考从前端传过来什么格式的数据,用什么去封装的问题?
    响应数据:图片的URL、状态码{url: ' ' , status: 200}
    所以采用Map<String,Object>集合封装
    此时在参数上使用@RequestParam注解
@RestController

public class UploadController {

    /** 注入文件服务器访问地址 */

    @Value("${fileServerUrl}")

    private String fileServerUrl;

    /** 文件上传 */

    @PostMapping("/upload")

    public Map<String, Object> 
upload(@RequestParam("file")MultipartFile multipartFile) {



        Map<String, Object> data = new HashMap<>();

        data.put("status", 500);

        try {

            /** 加载配置文件,产生该文件绝对路径 */

            String conf_filename = this.getClass()

                    .getResource("/fastdfs_client.conf").getPath();

            /** 初始化客户端全局对象 */

            ClientGlobal.init(conf_filename);

            /** 创建存储客户端对象 */

            StorageClient storageClient = new StorageClient();

   /** 获取文件名 */
           
String originalFilename =
                    multipartFile.getOriginalFilename();
           
/** 上传文件到FastDFS服务器 */
           
String[] arr = storageClient
                    .upload_file(multipartFile.getBytes(),
                FilenameUtils.getExtension(originalFilename),
null);
           
/** 拼接返回的 url ip 地址,拼装成完整的 url */
           
StringBuilder url = new StringBuilder(fileServerUrl);
           
for (String str : arr){
                url.append(
"/" + str);
            }
            data.put(
"status", 200);
            data.put(
"url", url.toString());
        }
catch (Exception e) {
            e.printStackTrace();
        }
       
return data;
    }
}
 


2.1 图片列表(包含了图片数据的封装)

商家后台-商品录入【商品图片上传】 

商家后台-商品录入【商品图片上传】 

  •  点击保存按钮,需要将图片显示在页面上面。
  • 图片列表:
       -- 商品图片保存到tb_goods_desc 的 item_images 列
          [{"color":"金色",
            "url":"http://image.pinyougou.com/jd/wKgMg1qtKEOATL9nAAFti6upbx4132.jpg"},
           {"color":"深空灰色",
           "url":"http://image.pinyougou.com/jd/wKgMg1qtKHmAFxj7AAFZsBqChgk725.jpg"},
           {"color":"银色",
           "url":"http://image.pinyougou.com/jd/wKgMg1qtKJyAHQ9sAAFuOBobu-A759.jpg"}]
          $scope.goods.goodsDesc.itemImages = [];

goods_edit.html修改上传窗口的保存按钮,绑定点击事件

<button class="btn btn-success" data-dismiss="modal"
     
ng-click="addPic()"
      aria-hidden="true"
>保存</button> 

sunny-shop-web/src/main/webapp/js/controller/goodsController.js增加方法 

/** 定义数据存储结构 */
$scope.goods = { goodsDesc : { itemImages : []}};
/** 添加图片到数组 */
$scope.addPic = function(){
   $scope.
goods.goodsDesc.itemImages.push($scope.picEntity);
};

goods_edit.html迭代图片列表(140行左右)

<tr ng-repeat="pic in goods.goodsDesc.itemImages">
   <
td>{{pic.color}}</td>
   <
td><img alt="" src="{{pic.url}}"
         
width="100px" height="100px"
></td>
   <
td>
      <
button type="button" class="btn btn-default" title="删除">
         <
i class="fa fa-trash-o"></i> 删除
     
</button>
   </
td>
</
tr> 

2.2 移除图片

 goods_edit.html修改列表中的删除按钮,绑定点击事件

<button type="button" class="btn btn-default" title="删除"
     
ng-click="removePic($index)"
>
   <
i class="fa fa-trash-o"></i> 删除</button>

sunny-shop-web/src/main/webapp/js/controller/goodsController.js增加代码 

/** 数组中移除图片 */
$scope.removePic = function(index){
    $scope.
goods.goodsDesc.itemImages.splice(index, 1);
};