34分布式电商项目 - 商品录入(图片上传至fastdfs)

简介: 34分布式电商项目 - 商品录入(图片上传至fastdfs)

上传图片至fastdfs

后端代码

1.pinyougou-common 工程 pom.xml 引入依赖

<!-- 文件上传组件 -->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
    </dependency>
    <dependency>
      <groupId>org.csource.fastdfs</groupId>
      <artifactId>fastdfs</artifactId>
    </dependency>

2.编写工具类 FastDFSClient.java

package com.pyg.utils;
public class FastDFSClient {
  private TrackerClient trackerClient = null;
  private TrackerServer trackerServer = null;
  private StorageServer storageServer = null;
  private StorageClient1 storageClient = null;
  public FastDFSClient(String conf) throws Exception {
    if (conf.contains("classpath:")) {
      conf = conf.replace("classpath:", this.getClass().getResource("/").getPath());
    }
    ClientGlobal.init(conf);
    trackerClient = new TrackerClient();
    trackerServer = trackerClient.getConnection();
    storageServer = null;
    storageClient = new StorageClient1(trackerServer, storageServer);
  }
  /**
   * 上传文件方法
   * <p>Title: uploadFile</p>
   * <p>Description: </p>
   * @param fileName 文件全路径
   * @param extName 文件扩展名,不包含(.)
   * @param metas 文件扩展信息
   * @return
   * @throws Exception
   */
  public String uploadFile(String fileName, String extName, NameValuePair[] metas) throws Exception {
    String result = storageClient.upload_file1(fileName, extName, metas);
    return result;
  }
  public String uploadFile(String fileName) throws Exception {
    return uploadFile(fileName, null, null);
  }
  public String uploadFile(String fileName, String extName) throws Exception {
    return uploadFile(fileName, extName, null);
  }
  /**
   * 上传文件方法
   * <p>Title: uploadFile</p>
   * <p>Description: </p>
   * @param fileContent 文件的内容,字节数组
   * @param extName 文件扩展名
   * @param metas 文件扩展信息
   * @return
   * @throws Exception
   */
  public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas) throws Exception {
    String result = storageClient.upload_file1(fileContent, extName, metas);
    return result;
  }
  public String uploadFile(byte[] fileContent) throws Exception {
    return uploadFile(fileContent, null, null);
  }
  public String uploadFile(byte[] fileContent, String extName) throws Exception {
    return uploadFile(fileContent, extName, null);
  }
}

3.把fdfs_client.conf文件拷贝到pinyougou-shop-web

工程 config 文件夹中。

4.在 pinyougou-shop-web 工程 application.properties 添加配置

5.在 pinyougou-shop-web 工程 springmvc.xml 添加配置:

<!-- 配置文件上传支持 -->
  <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 支持上传文件大小  -->
    <property name="maxUploadSize" value="1024000000"></property>
  </bean>

6.在 pinyougou-shop-web 新建 UploadController.java

@RestController
@RequestMapping("/shop")
public class UploadController {
  //注入常量配置
  @Value("${IMAGE_SERVER_URL}")
  private String IMAGE_SERVER_URL;
  /**
   * 需求:商家上传图片
   * 请求:upload
   * 参数:MultipartFile
   * 返回值:PygResult
   */
  @RequestMapping("/upload")
  public PygResult uploadPic(MultipartFile file){
    try {
      //获取文件名称
      String originalFilename = file.getOriginalFilename();
      //截取文件扩展名 
      String extName = originalFilename.substring(originalFilename.lastIndexOf(".")+1);
      //创建工具类对象
      FastDFSClient fdfs = new FastDFSClient("classpath:config/client.conf");
      //上传文件
      //gif,bmp,jpg
      //返回文件上传成功地址:group1/M00/00/02/wKhCQ1qvKG2AZqibAA1rIuRd3Es806.jpg
      String url = fdfs.uploadFile(file.getBytes(), extName);
      //组合图片上传成功绝对地址
      url = IMAGE_SERVER_URL+url;
      //上传成功
      return new PygResult(true, url);
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      //上传失败
      return new PygResult(false, "上传失败");
    }
  }
}

前端代码

1.在 pinyougou-shop-web 工程创建 uploadService.js

//文件上传服务层
app.service("uploadService",function($http){
  this.uploadFile=function(){
    var formData=new FormData();
    formData.append("file",file.files[0]); 
    return $http({
       method:'POST',
       url:"../upload.do",
       data: formData,
       headers: {'Content-Type':undefined},
       transformRequest: angular.identity
     });
  }
});

anjularjs 对于 post 和 get 请求默认的 Content-Type header 是 application/json。通过设置‘Content-Type’: undefined,这样浏览器会帮我们把 Content-Type 设置为 multipart/form-data.

通过设置 transformRequest: angular.identity ,anjularjs transformRequest function 将序列化我们的 formdata object.

2.将 uploadService 服务注入到 goodsController 中

//商品控制层(商家后台)
app.controller('goodsController' ,function($scope,$controller ,goodsService,itemCatService,uploadService){

3.在 goods_edit.html 引入 js

<script type="text/javascript" src="../js/base.js"> </script>
<script type="text/javascript" src="../js/service/goodsService.js"> </script>
<script type="text/javascript" src="../js/service/itemCatService.js"> </script>
<script type="text/javascript" src="../js/service/uploadService.js"> </script>
<script type="text/javascript" src="../js/controller/baseController.js"> </script>
<script type="text/javascript" src="../js/controller/goodsController.js"> </script>

4.上传图片,goodsController 编写代码

/**
* 上传图片
*/
$scope.uploadFile=function(){ 
  uploadService.uploadFile().success(function(response) { 
     if(response.success){//如果上传成功,取出 url
     $scope.image_entity.url=response.message;//设置文件地址
   }else{
     alert(response.message);
   }
   }).error(function() {
      alert("上传发生错误");
    }); 
  };

5.修改图片上传窗口,调用上传方法,回显上传图片

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



目录
相关文章
|
2月前
|
缓存 NoSQL Java
分布式项目中锁的应用(本地锁-_redis【setnx】-_redisson-_springcache)-fen-bu-shi-xiang-mu-zhong-suo-de-ying-yong--ben-de-suo--redissetnx-springcache-redisson(一)
分布式项目中锁的应用(本地锁-_redis【setnx】-_redisson-_springcache)-fen-bu-shi-xiang-mu-zhong-suo-de-ying-yong--ben-de-suo--redissetnx-springcache-redisson
59 0
|
2月前
|
SpringCloudAlibaba Java 持续交付
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
172 0
|
2月前
|
XML NoSQL Java
Java单体项目和分布式项目中的锁
Java单体项目和分布式项目中的锁 Java单体项目和分布式项目中的锁
32 2
|
2月前
|
缓存 NoSQL Redis
分布式项目中锁的应用(本地锁-_redis【setnx】-_redisson-_springcache)-fen-bu-shi-xiang-mu-zhong-suo-de-ying-yong--ben-de-suo--redissetnx-springcache-redisson(二)
分布式项目中锁的应用(本地锁-_redis【setnx】-_redisson-_springcache)-fen-bu-shi-xiang-mu-zhong-suo-de-ying-yong--ben-de-suo--redissetnx-springcache-redisson
39 0
|
3月前
|
存储 NoSQL 文件存储
C++ 哈希表企业级项目运用---淘宝分布式文件系统
C++ 哈希表企业级项目运用---淘宝分布式文件系统
|
4月前
|
网络协议 Devops 大数据
【分布式】大型互联网项目特点
【1月更文挑战第25天】【分布式】大型互联网项目特点
|
4月前
|
存储 缓存 监控
【分布式】大型互联网项目架构目标
【1月更文挑战第25天】【分布式】大型互联网项目架构目标
|
6天前
|
NoSQL Java 关系型数据库
【Redis系列笔记】分布式锁
分布式锁:满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心思想就是让大家都使用同一把锁,只要大家使用的是同一把锁,那么我们就能锁住线程,不让线程进行,让程序串行执行,这就是分布式锁的核心思路
28 2
|
1天前
|
监控 NoSQL 算法
探秘Redis分布式锁:实战与注意事项
本文介绍了Redis分区容错中的分布式锁概念,包括利用Watch实现乐观锁和使用setnx防止库存超卖。乐观锁通过Watch命令监控键值变化,在事务中执行修改,若键值被改变则事务失败。Java代码示例展示了具体实现。setnx命令用于库存操作,确保无超卖,通过设置锁并检查库存来更新。文章还讨论了分布式锁存在的问题,如客户端阻塞、时钟漂移和单点故障,并提出了RedLock算法来提高可靠性。Redisson作为生产环境的分布式锁实现,提供了可重入锁、读写锁等高级功能。最后,文章对比了Redis、Zookeeper和etcd的分布式锁特性。
25 6
探秘Redis分布式锁:实战与注意事项
|
2天前
|
NoSQL Java 大数据
介绍redis分布式锁
分布式锁是解决多进程在分布式环境中争夺资源的问题,与本地锁相似但适用于不同进程。以Redis为例,通过`setIfAbsent`实现占锁,加锁同时设置过期时间避免死锁。然而,获取锁与设置过期时间非原子性可能导致并发问题,解决方案是使用`setIfAbsent`的超时参数。此外,释放锁前需验证归属,防止误删他人锁,可借助Lua脚本确保原子性。实际应用中还有锁续期、重试机制等复杂问题,现成解决方案如RedisLockRegistry和Redisson。