龙空技术网

SpringCloud微服务架构实战使用分布式文件系统DFS

程序员高级码农II 3506

前言:

今天咱们对“怎么用ajax实现分页查询数据的方法”大致比较关心,同学们都想要了解一些“怎么用ajax实现分页查询数据的方法”的相关资讯。那么小编也在网摘上汇集了一些有关“怎么用ajax实现分页查询数据的方法””的相关资讯,希望你们能喜欢,各位老铁们快快来学习一下吧!

使用分布式文件系统 DFS

微服务应用使用分布式方式进行部署,并且有可能随时随地部署多个副本,所以必须有一个独立的文件系统来管理用户上传和使用的资源文件,包括图片和视频等。

在模块goods-web 的设计中,我们是使用FastDFS这个轻量级的分布式文件系统来设计的。如果使用云服务商提供的对象存储服务来设计,如OSS服务等,则可以参照服务提供商的使用说明,并结合本实例进行设计。

下面针对库存管理中,商品创建和编辑时使用的图片,实现在FastDFS上进行存储和管理的设计。

有关FastDFS的安装、集群构建和相关配置等,将在运维部署部分的相关章节中进行介绍。

分布式文件系统客户端开发

FastDFS 提供了Java语言使用的客户端开发包,但在Spring Boot中使用时还需要进行二次开发。为了简化开发过程,我们使用tobato在GitHub上开源的一个专为Spring Boot开发者提供的封装。

首先,在goods-web模块中,增加如下依赖引用:

<dependency><groupId>com.github.tobato</groupId><artifactId>fastdfs-client</artifactId><version>1.26.4-RELEASE</version></dependency>

然后,在模块的配置文件application.yml 中增加如下配置:

fdfs:soTimeout: 1501connectTimeout:601thumbImage:width: 150height: 150trackerList:- 192.168.1.214:22122-192.168.1.215:22122spring.jmx.enabled: falsefile.path.head:

这个配置假设 FastDFS 的TrackerServer安装了两台服务器,它们的P地址分别为“192.168.1.214”和“192.168.1.215”,并且可以通过链接“http:/192.168.1.214:8080/”使用文件。

接着,在工程的启动文件中增加注解@Import和@EnableMBeanExport,即导入fastdfs-client的相关配置,代码如下所示:

@SpringBootApplication@EnableDiscoveryClient@EnableFeignClients (basePackages = "com.demo")@componentScan(basePackages = "com.demo")R Import(FdfsClientConfig.class)@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)public class GoodswebApplication {public static void main(String[]args) {SpringApplication.run (GoodsWebApplication.class, args);}}

为了确认上面的引用和配置都已经准备就绪,可以启动应用验证一下。如果启动应用正常,则说明上面的配置是正确的。

现在,我们就可以创建一个“FastefsClient”实现文件的上传功能了,代码如下所示:

@servicepublic class FastefsClient {@Autowiredprotected FastFileStorageClient storageClient;public String uploFile (MultipartFile file){String fileType=FilenameUtils.getExtension(file.get0riginalFilename ()).toLowerCase();StorePath path =null;try {path = storageclient.uploadFile(file.getInputstream(),file.getsize(, fileType, nul1);Jcatch (IOException e){e.printstackTrace();}if(path !=null) {return path.getFu1lPath(;}else {return null;}public string uploile(Inputstream inputstream,Long size, String type)(StorePath path = null;try {path = storageclient.uploadFile(inputStream, size, type, null);}catch(Exception e){e.printStackTrace();}if(path!=null) {return path. getFullPath();}else ireturn null;public boolean deleteFile(string fullPath)try {storageClient.deleteFile(fullPath);return true;}catch(Exception e){e-printstackTrace(;}return false;}}

这里,设计了一个多态的uploFile方法,可以使用不同的参数通过调用FastFileStorageClient实现文件上传,同时设计了一个deleteFile方法,实现文件的删除操作。

商品图片上传设计

商品图片上传步骤如下。

首先,设计一个控制器PicUtilController;然后,在这个控制器中实现文件上传的功能,代码如下所示:

@Controller@RequestMapping("/pic")public class PicUtilController {@value("${file.path.head:}")private String pathHead;GAutowiredprivate FastefsClient fastefsClient;//可缩放图片上传CRequestMapping ("/upload")public String upload() {return "pic/upload-pic";}/*★*上传图片* @return大/@RequestMapping(value = "/uploadPic", method =RequestMethod. POST)public void uploadPic(@RequestParam ("pictureFile") MultipartFilemultipartFile,HttpServletRequest request,HttpServletResponse response)try{String filename = fastefsclient.uploFile (multipartFile);Long shopid =1L;AsyncThreadPool.getInstance().execute(new Runnable()(Goverridepublic void run(){try{savePic(multipartFile, filename ,shopid);]catch (Exception e){e.printStackTrace();});BufferedImage image = ImageIO.read(multipartFile.getInputStream());Map<String,0bject> data = new HashMap<String,0bject>();data.put("pathInfo", pathHead+filename);data.put("width", image.getWidth());data.put ("height", image.getHeight());ObjectMapper mapper = new ObjectMapper();String ret = mapper.writeValueAsString(data);response.setContentType("text/html; charset=utf8");response.getOutputStream().write(ret. getBytes());response.flushBuffer();}catch (IOException e){e.printStackTrace();}}...}

这个控制器设计了一个链接“/upload”,用来打开上传文件的操作界面。另外,另一个链接“/uploadPic”通过调用前面设计的文件客户端“FastefsClient”实现文件上传。上传后再将图片的路径和文件大小等信息返回给调用者。

在上面的代码中,文件上传的操作界面在视图设计“upload-pic.html”(源代码文件代码行30~33行)中实现,主要使用一个“input”控件从操作者的机器上选取文件进行上传,代码如下所示:

<div class="upload-box">//点击上传<input id="pictureFile" name="pictureFile" type="file" class="file"onchange="uploadPic submit (this)"/></div>

通过“upload-page.,js”(源代码文件代码行432~437行)设计一个文件上传的请求方法,即可在视图界面上调用上面的控制器设计中上传文件的链接“/uploadPic”了。调用成功后再取出文件信息,代码如下所示:

//上传图片function ajaxFileUpload(id){var url = '/pic/uploadPic';$.ajaxFileUpload({url :url,//需要链接到服务器地址fileElementId : id, //文件选择框的id属性dataType : 'json',//服务器返回的格式,可以是jsonsuccess:function(data){if(data.errorMsg){showMsg(data.errorMsg,"错误");}else{page.upload.finish(data.pathInfo, data.width, data.height);}}}};}

通过上述方法获取到文件信息之后,再通过“upload-pic.html”(源代码文件代码行53~80行)视图展现出来,这部分的设计代码如下所示:

<div class="img-select"><div class="up-tit">选择图片后可以在下框中调整您所需的部分。</div><div class=" operateBox"><span>上传图片后预览</span><div class=" operate" id="operate"><img/><div class="isee"><div class="b top"></div><div class="b_right"></div><div class="bbottom" ></div><div class="b left"></div><div class="handle h_top_left"></div><div class="handle h top"></div><div class="handle h_top right"></div><div class="handle h_right"></div><div class="handle hbottom right"></div><div class="handle h_bottom"></div><div class="handle h bottom_left"></div><div class="handle h_left"></div><div class="s_c"></div></div><div class="o_bg bg_top"></div><div class="o_bg bg_right"></div><div class="o_bg bg_bottom"></div><div class="o_bg bg_left"></div></div></div></div>

上面的设计完成后,最后显示的效果如图7-5所示。

其中,在进行图片选取时,还可以对图片进行裁剪,有关这部分的功能请查看项目的源代码。

注意,在进行上面的整个调试时,必须保证有分布式文件系统服务可以访问。

富文本编辑器上传图片设计

在库存管理中,对商品内容的编辑建议使用富文本编辑器,这样可以编辑出图文并茂的内容。使用富文本编辑器上传图片的原理与7.7.2节中的图片上传的设计基本相同。

这里以使用开源的ueditor富文本编辑器为例进行说明。

在控制器PicUtilController的设计中,使用如下所示的uploadimg方法设计:@controller@RequestMapping("/pic")public class PicUtilController {evalue("${file.path.head:}")private String pathHead;@Autowiredprivate FastefsClient fastefsClient;//ueditor 图片上传@RequestMapping (value = "/uploadimg", method= RequestMethod. POST,produces="text /html; charset=UTE-8")public void uploadimg(CRequestParam ( "upfile") MultipartFile upfile,HttpServletRequest request,HttpServletResponse response){try {String filename= fastefsclient. uploFile(upfile);Long shopid =1L;AsyncThreadPool.getInstance() .execute(new Runnable(){coverride .public void run() {try {savePic(upfile,filename , shopid);}catch(Exception e){e-printStackTrace();}}}};Map<String,0bject> data = new HashMap<String,0bject>();data.put ("original",upfile.getOriginalFilename());data.put("url",pathHead+filename);data.put("title","");data.put ("state", "sUCCESS");ObjectMapper mapper =new 0bjectMapper();String ret = mapper.writevalueAsString (data);response.setContentType ("text/html; charset=utf8");response.getOutputStream().write(ret.getBytes());response.flushBuffer(;}catch (Exception e){e.printStackTrace();}}}

与商品图片上传设计不同的地方是返回参数有点不一样,主要是根据ueditor插件的需要进行调整和设定。

在新增商品new.html和编辑商品edit.html的页面上增加如下所示代码,引用ueditor插件:

<script type="text/javascript" charset="utf-8">window.UEDITOR_HOME_ URL = "/ueditor/";</script><script type="text/javascript" charset="utf-8"th:src="@{/ueditor/editor_config.js} "></script><script type="text/javascript" charset="utf-8"th:src="@{/ueditor/editor_all.js} "></script><script type="text/javascript">var ME=UE .getEditor('contents',{wordCount:false,initialFramewidth: 406,maximumwords:50000,wordoverFlOwMsg:'最多输入50000个字符,toolbars:[[ ' fullscreen', 'undo', 'redo', 'l','bold','underline','strikethrough', 'superscript', 'subscript', 'removeformat','formatmatch', 'autotypeset', 'I', 'forecolor','backcolor', 'cleardoc', 'T','rowspacingtop', 'rowspacingbottom ' ,' lineheight','I','justifyleft', 'justifycenter','justifyright', 'justifyjustify','I', 'imagenone', 'imageleft',' imageright', 'imagecenter','l','customstyle','paragraph', 'fontsize','l', 'emotion', 'date', 'time', 'spechars','L','searchreplace', 'insertimage', 'wordimage','link ']]});</script>

最后,必须在ueditor 插件的配置文件“editor_config.js”(源代码文件代码行38~41行)中,更改如下所示的几行配置:

//图片上传配置区, imageUrl: " /pic/uploadimg"//图片上传提交地址, imagePath:""//图片修正地址,引用了fixedImagePath,如有特殊需求,可自行配置,imageFieldName: "upfile"//图片数据的 key,若此处修改,需要在后台对应文件修改对应参数

这样,就可以使用富文本编辑器上传图片文件了。

设计完成后,显示的效果如图7-6所示。

建立本地文件信息库

当一个文件上传之后,为了方便以后可以继续使用这个文件,我们可以在本地建立一个文件信息库,用来保存一个文件的简要信息。实现方法如下。

首先,有关数据服务的设计部分在模块goods-restapi 中。本地信息的图片数据对象:

@Table(name = "t picture")@Datapublic class Picture{@Id@Generatedvalue(strategy =GenerationType.IDENTITY)private Long id;//图片编号@column(name = "path info")private String pathInfo;//文件路径Ccolumn(name = "file name")private String fileName;//文件名private int width;//宽度private int height;//高度private String flag;//标志@DateTimeFormat (pattern = "yyyy-MM-dd HH:mm:ss")ecolumn (name = "created",columnDefinition = "timestamp defaultcurrent_timestamp")@Temporal (TemporalType.TIMESTAMP)private Date created;//创建时间private Long merchantid;//商家编号}

对应的数据库表结构t _picture的定义:

CREATE TABLE 'tpicture'('id' bigint (20) NOT NULL AUTO_INCREMENT,'created'timestamp NOT NULL DEFAULT CURRENT TIMESTAMP,'file_name' varchar(255)COLLATE utf8 bin DEFAULT NULL,'flag'varchar(255)COLLATE utf8 bin DEFAULT NULL,'height' int(11) DEFAULT NULL,'merchantid' bigint (20) DEFAULT NULL,'path info' varchar(255)COLLATE utf8_bin DEEAULT NULL,'width' int(11) DEFAULT NULL,PRIMARY KEY ('id')ENGINE=InnoDB AUTO INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

有关本地图片信息库的数据服务部分的实现,可以参照商品数据服务的设计方法,不再赘述。成功上传文件之后,如何将文件的路径和简要信息保存到本地文件信息库中呢?

文件信息保存在控制器PicUtilController 的savePic方法中,代码如下所示:

@controller@RequestMapping("/pic")public class PicUtilController {Value("${file.path.head:}")private string pathHead;CAutowiredprivate PictureRestService pictureRestService;private String savePic(MultipartFile multipartFile,String filename,Longshopid) throws Exception{BufferedImage image = ImageI0.read (multipartFile.getInputStream ());PictureQo picture= new PictureQ0();picture.setFileName (filename);picture.setHeight (image. getHeight ());picture.setWidth(image.getwidth());picture.setPathInfo(pathHead);picture.setMerchantid(shopid);return pictureRestService.create(picture);}}

在使用了本地文件信息库之后,在库存管理中创建和编辑商品时就可以使用已经上传的文件了。

为了能够更好地使用本地文件信息库,我们需要在控制器PicUtilController中创建一个分页查询本地文件信息库的方法 listPic,代码如下所示:

@controller@RequestMapping("/pic")public class PicUtilController{@value("${file.path.head:}")private String pathHead;@Autowiredprivate PictureRestService pictureRestService;@RequestMapping(value = "/listPic",method = RequestMethod.POST)@ResponseBodypublic Page<Map<String,0bject>>listPic(PictureQo pictureQo){String json = pictureRestService.findPage (pictureQo);Gson gson = TreeMapConvert.getGson();TreeMap<String, 0bject> page = gson.fromJson(json,new TypeToken<TreeMap<String, Object>>(){}.getType());Pageable pageable = PageRequest.of(pictureQo.getPage(),pictureQo.getSize( , null);java.util.List<PictureQ0> list = new ArrayList<>();if(page != null && page.get ("list") !=null) {list = gson.fromJson (page.get ("list").toString(), newTypeToken<List<PictureQ0>>() {}.getType());String count - page.get( "total").toString();return new PageImpl(list, pageable,new Long ( count));}}

其中,控制器使用链接“/listPic”为页面设计提供调用方法,返回本地文件信息的分页列表。

在页面上使用脚本定义upload-page.,js(源代码文件代码行501~525行),实现文件信息库分页查询结果的处理方法,代码如下所示:

function getDataHtml (pageNo, pagesize) {$.ajax(iurl: "/pic/listPic",dataType: "json",type: "POST",cache: false,data: {page: pageNo-1,size: pagesize ll 8},success:function (data){var $list =$('#upload-list').empty();$.each (data.content, function (i, v) {var html ="";html +='<div class="upload-item">'+'<div class="img"><img src="'+ v.pathInfo + v.fileName +"/></div>'+'<p>'+v.width+'x'+ v.height+'</p>'+'<div class="selected"></div>'+'</div>';$list.append($ (html));})page.photos.setPosition(;document.getElementById('pagebar').innerHTML=PageBarNumList.getPageBar (data.number+1, data.totalPages,3,'getDataHtml',pagesize ll8,true);},errOr: function (e) {}});}

设计完成之后,展示的效果如图7-7所示。

总体测试

在库存管理项目整体开发完成之后,可以进行一个总体测试。这个测试需要调用类目管理的微服务接口,所以在进行测试时,可按下列顺序启动各个模块。

(1)启动类目接口服务:catalog-restapi模块。

(2)启动库存管理微服务API应用:goods-restapi模块。

(3)启动库存管理PC端Web应用:goods-web模块。

上面几个模块启动成功之后,可在浏览器打开如下链接地址:

如果各个模块都能正常运行,则可以在库存管理首页中显示已有的商品列表,如图7-8所示。

在这个页面中,我们可以新增或者编辑商品。编辑商品的操作界面如图7-9所示。

小结

本章介绍了库存管理的微服务接口和一个相关的Web应用微服务的开发。在这个项目的开发过程中,我们使用了半自动的数据库开发框架MyBatis,体验了与使用JPA不同的开发实践。在生产应用中,读者可以根据实际情况选择使用。

同时,本章的Web应用开发也演示了使用分布式文件系统的方法,不管是使用DFS,还是使用OSS,其设计思路和实现方法基本一致,所以我们只需掌握一种开发方法,就能够在实际应用中应用自如。

本文给大家讲解的内容

SpringCloud微服务架构实战:库存管理与分布式文件系统,使用分布式文件系统DFS、总体测试

下篇文章给大家讲解的是SpringCloud微服务架构实战:海量订单系统微服务开发;觉得文章不错的朋友可以转发此文关注小编;感谢大家的支持!

标签: #怎么用ajax实现分页查询数据的方法