SOA architecture - server application Taotao store pictures and rich text editor

table of Contents

Today's goal:

1 Select product category

1.1 Classification prototype

1.2 Functional Analysis

1.2.1 Asynchronous tree control

1.2.2 Looking categories

1.2.3 Select Category initialize components:

1.2.4 query table:

1.3 Dao layer

1.4 Service Layer

2 image upload analysis

3 image server installation

3.1 What is FastDFS?

3.3 file upload process

3.4 Download

3.5 The simplest architecture FastDFS

4 image server installation method

4.1 Installation Steps

5 image server use

5.1 Java client:

5.2 Maven environment:

5.3 upload pictures

5.3.1 Code

5.4 Use tools to upload

6 image upload feature

6.1 Functional Analysis

6.2 Controller

6.3 to solve the problem of browser compatibility

7 Use the rich text editor

Rich Text Editor 7.1 Introduction

7.2 Use

8 items to add functions to achieve

8.1 Functional Analysis

8.2 Dao layer

8.3 Service Layer

8.3.1 Publishing Service

8.4 Presentation Layer

9 shows the results of the third day:

9.1 realization of goods display

9.2 Query achieve category


Today's goal:

  1. Select product category
  2. upload picture
  3. Image server FastDFS
  4. Image upload feature to achieve
  5. Rich text editor using KindEditor
  6. Items to add functionality to complete

1 Select product category

1.1 Classification prototype

A tree structure, such as buy a book, first find the book, wanted the tree, and then find the leaves, about computers, mathematics, and foreign literature about this!

1.2 Functional Analysis

1.2.1 Asynchronous tree control

Built-in support asynchronous tree control loading mode, the user first creates an empty tree and specifies a server, dynamic retrieval of JSON data to populate the tree and perform asynchronous request to complete.

That is, look at that load that category!

Display Categories list, use the tree control EasyUI show.

Tree initialization request url: / item / cat / list

parameter:

Just need to show the first level node initialization tree, child nodes asynchronous loading.

long id (parent id)

Return value: json. Data Format

[{    
    "id": 1,    
    "text": "Node 1",    
    "state": "closed"
},{    
    "id": 2,    
    "text": "Node 2",    
    "state": "closed"   
}] 


state: If there is a child node "closed", if no child nodes "open" under node

Pojo Create a tree node information will be described, including three attributes id, text, state. Put taotao-common project.

public class EasyUITreeNode implements Serializable{

	private long id;
	private String text;
	private String state;
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getText() {
		return text;
	}
	public void setText(String text) {
		this.text = text;
	}
	public String getState() {
		return state;
	}
	public void setState(String state) {
		this.state = state;
	}
	
}

 And at this time there is no button, there is no binding instructions have configured in the external js

1.2.2 Looking categories

After finding one explanation is that he


1.2.3 Select Category initialize components:

 // 初始化选择类目组件
    initItemCat : function(data){
    	$(".selectItemCat").each(function(i,e){
    		var _ele = $(e);
    		if(data && data.cid){
    			_ele.after("<span style='margin-left:10px;'>"+data.cid+"</span>");
    		}else{
    			_ele.after("<span style='margin-left:10px;'></span>");
    		}
    		_ele.unbind('click').click(function(){
    			$("<div>").css({padding:"5px"}).html("<ul>")
    			.window({
    				width:'500',
    			    height:"450",
    			    modal:true,
    			    closed:true,
    			    iconCls:'icon-save',
    			    title:'选择类目',
    			    onOpen : function(){
    			    	var _win = this;
    			    	$("ul",_win).tree({
    			    		url:'/item/cat/list',
    			    		animate:true,
    			    		onClick : function(node){
    			    			if($(this).tree("isLeaf",node.target)){
    			    				// 填写到cid中
    			    				_ele.parent().find("[name=cid]").val(node.id);
    			    				_ele.next().text(node.text).attr("cid",node.id);
    			    				$(_win).window('close');
    			    				if(data && data.fun){
    			    					data.fun.call(this,node);
    			    				}
    			    			}
    			    		}
    			    	});
    			    },
    			    onClose : function(){
    			    	$(this).window("destroy");
    			    }
    			}).window('open');
    		});
    	});
    },
    
    createEditor : function(select){
    	return KindEditor.create(select, TT.kingEditorParams);
    },
    

1.2.4 query table:

tb_item_cat

Query column:

Id、name、isparent

Query parentId

1.3 Dao layer

tb_item_cat

You can use the generated code reverse engineering, basic CRUD have a single table, saved a lot of thing, do not have to write.

1.4 Service Layer

Parameters: long parentId

Business logic:

  1. According parentId query node list
  2. Converted into EasyUITreeNode list.
  3. return.

Return Value: List <EasyUITreeNode>

@Service
public class ItemCatServiceImpl implements ItemCatService {

	@Autowired
	private TbItemCatMapper itemCatMapper;
	
	
	@Override
	public List<EasyUITreeNode> getCatList(long parentId) {
		// 1、根据parentId查询节点列表
		TbItemCatExample example = new TbItemCatExample();
		//设置查询条件
		Criteria criteria = example.createCriteria();
		criteria.andParentIdEqualTo(parentId);
		List<TbItemCat> list = itemCatMapper.selectByExample(example);
		// 2、转换成EasyUITreeNode列表。
		List<EasyUITreeNode> resultList = new ArrayList<>();
		for (TbItemCat tbItemCat : list) {
			EasyUITreeNode node = new EasyUITreeNode();
			node.setId(tbItemCat.getId());
			node.setText(tbItemCat.getName());
			node.setState(tbItemCat.getIsParent()?"closed":"open");
			//添加到列表
			resultList.add(node);
		}
		// 3、返回。
		return resultList;
	}

}

Publishing Service

Presentation layer

Reference service

Controller

Tree initialization request url: / item / cat / list

parameter:

long id (parent id)

Return value: json. Data Format

 List<EasyUITreeNode>

@Controller
public class ItemCatController {

	@Autowired
	private ItemCatService itemCatService;
	@RequestMapping("/item/cat/list")
	@ResponseBody
	public List<EasyUITreeNode> getItemCatList(@RequestParam(value="id", defaultValue="0")Long parentId) {
		
		List<EasyUITreeNode> list = itemCatService.getCatList(parentId);
		return list;
	}
}

2 image upload analysis

The traditional way:

Clustered environments:

solution:

Pictures set up a server dedicated to save the image. You can use the Distributed File System FastDFS.

3 image server installation

  1. Storage space can be expanded.
  2. Provide a unified access method.

Use FastDFS, distributed file systems. Storage space may be laterally extended, highly available server may be implemented. Each node supports backup machine.

3.1 What is FastDFS?

FastDFS is written in c language an open source distributed file system. FastDFS tailor-made for the Internet, full account of redundancy, load balancing, and other mechanisms linear expansion, and focus on high availability, high performance and other indicators, it is easy to use FastDFS to build a high-performance file server clusters to provide file upload and download and other services.

3.2 FastDFS architecture

FastDFS architecture includes Tracker server and Storage server. Tracker server client requests for file upload, download, upload and download files finalized by the Storage server by Tracker server scheduling.

Tracker server role is load balancing and scheduling can be found Storage server to provide file upload service to Tracker server when the file is uploaded, according to some policies. tracker track server or may be referred to dispatch server.

Storage server role is a file stored on Storage server, Storage server does not implement its own file system client upload the final file storage but to use the operating system's file system to manage files. storage can be referred to as a storage server.

Two server roles:

Tracker: Management cluster, tracker can also be achieved clusters. Each tracker node equal footing.

Collecting state Storage cluster.

Storage: actually saving the file

Storage divided into groups, each group between saving files is different. Within each group can have more than one member, save a member of the internal group content is the same, the status of group members is the same, there is no concept of master and slave.

3.3 file upload process

After the client upload a file server to store the file ID is returned to the client, this ID file for later access index information for the file. File index information includes: group name, virtual disk paths, two data directory, file name.

  1. Group Name: storage group after the name of the file upload, file upload after the successful return has storage server, the client needs to save itself.
  2. Virtual disk path: Storage configuration of the virtual path, and disk options store_path * correspondence. If you configure store_path0 is M00, if you configure store_path1 is M01, and so on.
  3. Data two directories: storage server to create two directories in each virtual disk paths for storing data files.
  4. Different upload and file: the file name. Is based on specific information generated by the storage server, the file name contains: source IP address of the storage server, file creation time stamp, file size, the random number and filename extension and other information.

3.4 Download

3.5 The simplest architecture FastDFS

4 image server installation method

4.1 Installation Steps

The first step: the image server decompress.

Step two: Add a picture to a server in Vmware.

The third step: the network configuration of Vmware.

Step four: boot

Mobile: Network configuration does not change. To use the image server, you need to ensure that the network configuration unchanged.

Copy: Rebuild a network card mac address is a new address.

Ip Address: 192.168.25.133

Username root, itcast

Password: itcast

5 image server use

5.1 Java client:

5.2 Maven environment:

5.3 upload pictures

  1. Upload steps
  2. Loading a configuration file, the contents of the configuration file is the address tracker services.

Profile content: tracker_server = 192.168.25.133: 22122

  1. Creating a TrackerClient object. A new direct.
  2. Create a connection using TrackerClient object to obtain a TrackerServer object.
  3. StorageServer create a reference, value is null
  4. Creating a StorageClient object requires two parameters TrackerServer objects of reference StorageServer
  5. Use StorageClient objects to upload pictures.
  6. Returns an array. Contain the path name and picture of the group.

5.3.1 Code

public class FastDFSTest {

	@Test
	public void testFileUpload() throws Exception {
		// 1、加载配置文件,配置文件中的内容就是tracker服务的地址。
		ClientGlobal.init("D:/workspaces-itcast/term197/taotao-manager-web/src/main/resources/resource/client.conf");
		// 2、创建一个TrackerClient对象。直接new一个。
		TrackerClient trackerClient = new TrackerClient();
		// 3、使用TrackerClient对象创建连接,获得一个TrackerServer对象。
		TrackerServer trackerServer = trackerClient.getConnection();
		// 4、创建一个StorageServer的引用,值为null
		StorageServer storageServer = null;
		// 5、创建一个StorageClient对象,需要两个参数TrackerServer对象、StorageServer的引用
		StorageClient storageClient = new StorageClient(trackerServer, storageServer);
		// 6、使用StorageClient对象上传图片。
		//扩展名不带“.”
		String[] strings = storageClient.upload_file("D:/Documents/Pictures/images/200811281555127886.jpg", "jpg", null);
		// 7、返回数组。包含组名和图片的路径。
		for (String string : strings) {
			System.out.println(string);
		}
	}
}

5.4 Use tools to upload

test:

@Test
	public void testFastDfsClient() throws Exception {
		FastDFSClient fastDFSClient = new FastDFSClient("D:/workspaces-itcast/term197/taotao-manager-web/src/main/resources/resource/client.conf");
		String file = fastDFSClient.uploadFile("D:/Documents/Pictures/images/2f2eb938943d.jpg");
		System.out.println(file);
	}

 

6 image upload feature

6.1 Functional Analysis

Using KindEditor multi-image upload plugin.

KindEditor 4.x Document

http://kindeditor.net/doc.php

Request url: / pic / upload

Parameters: MultiPartFile uploadFile

Returns:
You can create a pojo the corresponding return value. You can use the map

  1. Need to commons-io, fileupload jar package added to the project.
  2. Configuring multimedia parser.
<!-- 定义文件上传解析器 -->
	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 设定默认编码 -->
		<property name="defaultEncoding" value="UTF-8"></property>
		<!-- 设定文件上传的最大值5MB,5*1024*1024 -->
		<property name="maxUploadSize" value="5242880"></property>
	</bean>

6.2 Controller

@Controller
public class PictureController {
	
	@Value("${IMAGE_SERVER_URL}")
	private String IMAGE_SERVER_URL;

	@RequestMapping("/pic/upload")
	@ResponseBody
	public Map fileUpload(MultipartFile uploadFile) {
		try {
			//1、取文件的扩展名
			String originalFilename = uploadFile.getOriginalFilename();
			String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
			//2、创建一个FastDFS的客户端
			FastDFSClient fastDFSClient = new FastDFSClient("classpath:resource/client.conf");
			//3、执行上传处理
			String path = fastDFSClient.uploadFile(uploadFile.getBytes(), extName);
			//4、拼接返回的url和ip地址,拼装成完整的url
			String url = IMAGE_SERVER_URL + path;
			//5、返回map
			Map result = new HashMap<>();
			result.put("error", 0);
			result.put("url", url);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			//5、返回map
			Map result = new HashMap<>();
			result.put("error", 1);
			result.put("message", "图片上传失败");
			return result;
		}
	}
}

6.3 to solve the problem of browser compatibility

KindEditor image upload plugin is not good for browser compatibility.

Use @ResponseBody annotation return java object,

Content-Type:application/json;charset=UTF-8

Return the string:

Content-Type:text/plan;charset=UTF-8

Specify the content-type response results:

7 Use the rich text editor

Rich Text Editor 7.1 Introduction

KindEditor

http://kindeditor.net/

UEditor: Baidu Editor

http://ueditor.baidu.com/website/

CKEditor

http://ckeditor.com/

Pure js development, nothing to do with the background language.

7.2 Use

The first step: introducing the KindEditor css and js code in the jsp.

Step two: add a textarea control to the form. The carrier is a rich text editor. Similar data source.

The third step: initialize the rich text editor. Use official initialization.

Step Four: Take the rich content of the text editor.

Before the form is submitted, the contents of the rich text editor is synchronized to the textarea control.

8 items to add functions to achieve

8.1 Functional Analysis

Request url: / item / save

Parameters: data form. Pojo can use data received form, required attribute name and attribute of the input pojo to be consistent.

Use TbItem object receives form data.

TbItem item,String desc

return value:

Json data. It should contain a status of property.

You may be used TaotaoResult, placed in taotao-common.

Business logic:

  1. Product id generation

Implementation:

  1. Uuid, strings, not recommended.
  2. Numeric type, will not be repeated. Date + time + random number 20160402151333123123
  3. + Milliseconds can go directly to the random number. can use.
  4. Use redis. Incr. Recommended Use.

Product id generated using IDUtils

  1. Completion TbItem object's properties
  2. Insert data product table
  3. Creating a TbItemDesc objects
  4. Completion TbItemDesc property
  5. Product description data to insert
  6. TaotaoResult.ok ()

8.2 Dao layer

, Tb_item_desc insert the data into tb_item

You can use reverse engineering

8.3 Service Layer

Parameters: TbItem item, String desc

Business logic: a little, to participate in the above

Return value: TaotaoResult

@Override
	public TaotaoResult addItem(TbItem item, String desc) {
		// 1、生成商品id
		long itemId = IDUtils.genItemId();
		// 2、补全TbItem对象的属性
		item.setId(itemId);
		//商品状态,1-正常,2-下架,3-删除
		item.setStatus((byte) 1);
		Date date = new Date();
		item.setCreated(date);
		item.setUpdated(date);
		// 3、向商品表插入数据
		itemMapper.insert(item);
		// 4、创建一个TbItemDesc对象
		TbItemDesc itemDesc = new TbItemDesc();
		// 5、补全TbItemDesc的属性
		itemDesc.setItemId(itemId);
		itemDesc.setItemDesc(desc);
		itemDesc.setCreated(date);
		itemDesc.setUpdated(date);
		// 6、向商品描述表插入数据
		itemDescMapper.insert(itemDesc);
		// 7、TaotaoResult.ok()
		return TaotaoResult.ok();
	}

8.3.1 Publishing Service

8.4 Presentation Layer

8.4.1 reference service

8.4.2 Controller

Request url: / item / save

Parameters: TbItem item, String desc

Return value: TaotaoResult

@RequestMapping("/save")
	@ResponseBody
	public TaotaoResult saveItem(TbItem item, String desc) {
		TaotaoResult result = itemService.addItem(item, desc);
		return result;
	}

9 shows the results of the third day:

9.1 realization of goods display

9.2 Query achieve category

Published 237 original articles · won praise 20 · views 20000 +

Guess you like

Origin blog.csdn.net/ZGL_cyy/article/details/105196591