table of Contents
1.2.1 Asynchronous tree control
1.2.3 Select Category initialize components:
3.5 The simplest architecture FastDFS
4 image server installation method
6.3 to solve the problem of browser compatibility
Rich Text Editor 7.1 Introduction
8 items to add functions to achieve
9 shows the results of the third day:
9.1 realization of goods display
Today's goal:
- Select product category
- upload picture
- Image server FastDFS
- Image upload feature to achieve
- Rich text editor using KindEditor
- 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:
- According parentId query node list
- Converted into EasyUITreeNode list.
- 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
- Storage space can be expanded.
- 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.
- 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.
- 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.
- Data two directories: storage server to create two directories in each virtual disk paths for storing data files.
- 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
- Upload steps
- Loading a configuration file, the contents of the configuration file is the address tracker services.
Profile content: tracker_server = 192.168.25.133: 22122
- Creating a TrackerClient object. A new direct.
- Create a connection using TrackerClient object to obtain a TrackerServer object.
- StorageServer create a reference, value is null
- Creating a StorageClient object requires two parameters TrackerServer objects of reference StorageServer
- Use StorageClient objects to upload pictures.
- 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
Request url: / pic / upload
Parameters: MultiPartFile uploadFile
Returns:
You can create a pojo the corresponding return value. You can use the map
- Need to commons-io, fileupload jar package added to the project.
- 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
UEditor: Baidu Editor
http://ueditor.baidu.com/website/
CKEditor
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:
- Product id generation
Implementation:
- Uuid, strings, not recommended.
- Numeric type, will not be repeated. Date + time + random number 20160402151333123123
- + Milliseconds can go directly to the random number. can use.
- Use redis. Incr. Recommended Use.
Product id generated using IDUtils
- Completion TbItem object's properties
- Insert data product table
- Creating a TbItemDesc objects
- Completion TbItemDesc property
- Product description data to insert
- 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;
}