Relevant dependency
<!-- https://mvnrepository.com/artifact/net.oschina.zcx7878/fastdfs-client-java --> <dependency> <groupId>net.oschina.zcx7878</groupId> <artifactId>fastdfs-client-java</artifactId> <version>1.27.0.0</version> </dependency>
FastDFS Upload Client Tool Class
/** * FastDFS File System Client * @author: Kellan_Song * @date: 2019-08-04 21:12 **/ @Component public class FastDFSClient { private final String GROUP_NAME = "group1"; //Group name private TrackerClient trackerClient; private TrackerServer trackerServer; private StorageServer storageServer; private StorageClient storageClient; public FastDFSClient() throws Exception { ClientGlobal.initByTrackers("193.112.40.54:22122"); trackerClient = new TrackerClient(ClientGlobal.g_tracker_group); trackerServer = trackerClient.getConnection(); storageServer = trackerClient.getStoreStorage(trackerServer); storageClient = new StorageClient(trackerServer, storageServer); } /** * Upload files * @param file File object * @param fileName file name * @return */ public String[] uploadFile(File file, String fileName) { try { byte[] buff = IOUtils.toByteArray(new FileInputStream(file)); return uploadFile(buff, fileName, null); } catch (IOException e) { e.printStackTrace(); } return null; } /** * Upload files * @param buff File stream * @param fileName file name * @return */ public String[] uploadFile(byte[] buff, String fileName) { return uploadFile(buff, fileName, null); } /** * Upload files * @param file file * @return */ public String[] uploadFile(MultipartFile file) { try { return uploadFile(file.getBytes(), file.getOriginalFilename(), null); } catch (IOException e) { e.printStackTrace(); } return null; } /** * Upload files * * @param buff File stream * @param fileName file name * @param metaList meta-data * @return */ public String[] uploadFile(byte[] buff, String fileName, Map<String,String> metaList) { String prefix = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()); // File suffix name try { NameValuePair[] nameValuePairs = null; if (metaList != null) { nameValuePairs = new NameValuePair[metaList.size()]; int index = 0; for (Iterator<Map.Entry<String,String>> iterator = metaList.entrySet().iterator(); iterator.hasNext();) { Map.Entry<String,String> entry = iterator.next(); String name = entry.getKey(); String value = entry.getValue(); nameValuePairs[index++] = new NameValuePair(name,value); } } return storageClient.upload_file(GROUP_NAME, buff, prefix, nameValuePairs); } catch (Exception e) { e.printStackTrace(); } return null; } /** * Download files * @param fileId File ID (ID returned after successful upload) * @return */ public byte[] downloadFile(String fileId) { try { byte[] content = storageClient.download_file(GROUP_NAME,fileId); return content; } catch (Exception e) { e.printStackTrace(); } return null; } /** * Delete files * @param fileId File ID * @return Delete failed return - 1, otherwise return 0 */ public int deleteFile(String groupname,String fileId) { try { return storageClient.delete_file(groupname,fileId); } catch (Exception e) { e.printStackTrace(); } return -1; } /** * Getting file metadata * @param fileId File ID * @return */ public Map<String,String> getFileMetadata(String groupname,String fileId) { try { NameValuePair[] metaList = storageClient.get_metadata(groupname,fileId); if (metaList != null) { HashMap<String,String> map = new HashMap<String, String>(); for (NameValuePair metaItem : metaList) { map.put(metaItem.getName(),metaItem.getValue()); } return map; } } catch (Exception e) { e.printStackTrace(); } return null; } }
Explain
Core point is how to initialize the configuration file: ClientGlobal class commonly uses several initialization methods:
- init(String conf_filename)
- initByProperties(String propsFilePath)
- initByProperties(Properties props)
- initByTrackers(String trackerServers)
Core configuration parameters:
#Connecting tracker server timeout connect_timeout = 2 #socket connection timeout network_timeout = 30 #File Content Coding charset = UTF-8 #tracker server port http.tracker_http_port = 8080 http.anti_steal_token = no http.secret_key = FastDFS1234567890 #tracker server IP and ports (multiple writes) tracker_server = 192.168.1.190:22122
PS: Because the above example is just a demonstration, other configuration parameters ClientGlobal class have defaults, so the initialization parameter method used in the example can be directly passed into tracker_server's ip and port.
Error record:
1 java.net.SocketTimeoutException: connect timed out
Connection failure, as we have explored, can cause connection failure in the following two cases:
(1) Port not open
Because when using fastdfs-client-java, configuration only needs to configure the Tracker service address and port; this can easily lead to a misunderstanding that the external network port only needs to open the Tracker service port (default 22122). But in fact, Tracker service is only an intermediate service, it will get the available Storage service address and port, and the final file upload is directly uploaded to Storage service by the service we developed. Therefore, the server's external network port, must remember to open the Storage port (default 23000).
(2) Tracker address mismatch
Many people think that when configuring storage.conf, because both storage service and tracker service are on the intranet, intranet IP connections can be used. When the tracker address of Java service configuration belongs to the intranet gateway relationship, it needs to be configured as the extranet ip. But in fact, the tracker address of the Java service configuration, and the address of the storage. conf configuration, need to be accessible and consistent. One configures intranet IP and the other configures extranet ip, which causes a connection timed out error.