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>



目录
相关文章
|
7月前
|
NoSQL 调度 Redis
19- 你的项目中哪里用到了分布式锁
在一个项目中,为解决集群环境下SpringTask定时任务的重复执行问题,采用了Redis实现分布式锁来管理任务调度,防止资源浪费。后来因任务量和执行规则增加,以及单节点效率限制,系统改用XXL-JOB,分布式锁不再使用。
74 2
|
3月前
|
NoSQL Java Redis
面试官:项目中如何实现分布式锁?
面试官:项目中如何实现分布式锁?
100 6
面试官:项目中如何实现分布式锁?
|
4月前
|
资源调度 Java 调度
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
|
4月前
|
存储 缓存 开发框架
看看 Asp.net core Webapi 项目如何优雅地使用分布式缓存
看看 Asp.net core Webapi 项目如何优雅地使用分布式缓存
|
5月前
|
SQL NoSQL Java
如何在Java项目中实现分布式锁
如何在Java项目中实现分布式锁
|
5月前
|
消息中间件 Java 中间件
如何在Java项目中实现分布式事务管理
如何在Java项目中实现分布式事务管理
|
7月前
|
XML NoSQL Java
Java单体项目和分布式项目中的锁
Java单体项目和分布式项目中的锁 Java单体项目和分布式项目中的锁
96 2
|
2月前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
18天前
|
存储 NoSQL Java
使用lock4j-redis-template-spring-boot-starter实现redis分布式锁
通过使用 `lock4j-redis-template-spring-boot-starter`,我们可以轻松实现 Redis 分布式锁,从而解决分布式系统中多个实例并发访问共享资源的问题。合理配置和使用分布式锁,可以有效提高系统的稳定性和数据的一致性。希望本文对你在实际项目中使用 Redis 分布式锁有所帮助。
47 5
|
22天前
|
NoSQL Java 数据处理
基于Redis海量数据场景分布式ID架构实践
【11月更文挑战第30天】在现代分布式系统中,生成全局唯一的ID是一个常见且重要的需求。在微服务架构中,各个服务可能需要生成唯一标识符,如用户ID、订单ID等。传统的自增ID已经无法满足在集群环境下保持唯一性的要求,而分布式ID解决方案能够确保即使在多个实例间也能生成全局唯一的标识符。本文将深入探讨如何利用Redis实现分布式ID生成,并通过Java语言展示多个示例,同时分析每个实践方案的优缺点。
39 8
下一篇
DataWorks