【仅供内部供应商使用,不提供对外解答和培训】
【仅供内部供应商使用,不提供对外解答和培训】
1.新增一个entity
package com.fr.schedule.base.entity.output; import com.fr.schedule.base.bean.output.OutputFtp; import com.fr.schedule.base.entity.AbstractScheduleEntity; import com.fr.third.javax.persistence.Column; import com.fr.third.javax.persistence.Entity; import com.fr.third.javax.persistence.Table; /** * Created by Zed on 2017/12/21. * 定时任务,ftp的实体对象 */ @Entity @Table(name = "fine_output_ftp") //表名 @TableAssociation(associated = true) public class OutputFtpEntity extends AbstractScheduleEntity { public static final String COLUMN_SERVER_ADDRESS = "serverAddress"; public static final String COLUMN_PORT = "port"; public static final String COLUMN_SAVE_PATH = "savePath"; public static final String COLUMN_USERNAME = "username"; public static final String COLUMN_PASSWORD = "password"; @Column(name = COLUMN_SERVER_ADDRESS) private String serverAddress = null; @Column(name = COLUMN_PORT) private String port = null; @Column(name = COLUMN_SAVE_PATH) private String savePath = null; @Column(name = COLUMN_USERNAME) private String username = null; @Column(name = COLUMN_PASSWORD) private String password = null; public OutputFtpEntity() { } //转换成bean对象 @Override public OutputFtp createBean() { return new OutputFtp() .id(this.getId()) .serverAddress(this.getServerAddress()) .port(this.getPort()) .savePath(this.getSavePath()) .username(this.getUsername()) .password(this.getPassword()); } public OutputFtpEntity id(String id) { setId(id); return this; } public String getServerAddress() { return serverAddress; } public void setServerAddress(String serverAddress) { this.serverAddress = serverAddress; } public OutputFtpEntity serverAddress(String serverAddress) { setServerAddress(serverAddress); return this; } public String getPort() { return port; } public void setPort(String port) { this.port = port; } public OutputFtpEntity port(String port) { setPort(port); return this; } public String getSavePath() { return savePath; } public void setSavePath(String savePath) { this.savePath = savePath; } public OutputFtpEntity savePath(String savePath) { setSavePath(savePath); return this; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public OutputFtpEntity username(String username) { setUsername(username); return this; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public OutputFtpEntity password(String password) { setPassword(password); return this; } }
2.新增bean对象(用于和前台交互)
package com.fr.schedule.base.bean.output; import com.fr.schedule.base.entity.AbstractScheduleEntity; import com.fr.schedule.base.entity.output.OutputFtpEntity; import com.fr.schedule.base.type.RunType; import com.fr.third.fasterxml.jackson.annotation.JsonSubTypes; /** * Created by Zed on 2017/12/19. * 定时任务导出,发送ftp */ @JsonSubTypes.Type(value = OutputFtp.class, name = "OutputFtp") public class OutputFtp extends BaseOutputAction { private static final long serialVersionUID = 8245931480823179622L; private String serverAddress = null; private String port = null; private String savePath = null; private String username = null; private String password = null; public OutputFtp() { super(); } //是否受不同用户生成不同附件影响 @Override public boolean willExecuteByUser() { return false; } @Override public RunType runType() { return RunType.SEND_FTP; } //这里直接关联第一步的entity类 @Override public Class<? extends AbstractScheduleEntity> outputActionEntityClass() { return OutputFtpEntity.class; } //转换成entity对象,用于数据库存储,注意属性不要漏了 @Override public OutputFtpEntity createOutputActionEntity() { return new OutputFtpEntity() .id(this.getId()) .password(this.getPassword()) .serverAddress(this.getServerAddress()) .port(this.getPort()) .savePath(this.getSavePath()) .username(this.getUsername()); } public OutputFtp id(String id) { setId(id); return this; } public String getServerAddress() { return serverAddress; } public void setServerAddress(String serverAddress) { this.serverAddress = serverAddress; } public OutputFtp serverAddress(String serverAddress) { setServerAddress(serverAddress); return this; } public String getPort() { return port; } public void setPort(String port) { this.port = port; } public OutputFtp port(String port) { setPort(port); return this; } public String getSavePath() { return savePath; } public void setSavePath(String savePath) { this.savePath = savePath; } public OutputFtp savePath(String savePath) { setSavePath(savePath); return this; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public OutputFtp username(String username) { setUsername(username); return this; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public OutputFtp password(String password) { setPassword(password); return this; } }
3.新增一个handler,处理推送业务
package com.fr.schedule.feature.output; import com.fr.ftp.client.FTPClient; import com.fr.ftp.client.FTPReply; import com.fr.io.utils.ResourceIOUtils; import com.fr.schedule.base.bean.output.OutputFtp; import com.fr.schedule.base.constant.ScheduleConstants; import com.fr.stable.ArrayUtils; import com.fr.stable.StringUtils; import java.io.InputStream; import java.util.Map; /** * Created by Zed on 2018/01/10. */ public class FTPHandler extends OutputActionHandler<OutputFtp> { private static final int CONNECTION_TIME_OUT = 10000; private static final int DATA_TIME_OUT = 60000; // FTP协议里面,规定文件名编码为iso-8859-1 private static final String SERVER_CHARSET = "ISO-8859-1"; //本地字符编码 private static final String LOCAL_CHARSET = "GBK"; //如果ftp服务器是utf-8编码,需要转换 private static final String UTF8_CHARSET = "UTF-8"; @Override public void doAction(OutputFtp ftp, Map<String, Object> map) throws Exception { FTPClient client = null; try { String[] files = (String[]) map.get(ScheduleConstants.OUTPUT_FILES); client = createFtpClient(ftp); if (FTPReply.isPositiveCompletion(client.getReplyCode())) { //指向目录 changeFtpDir(client, ftp.getSavePath()); for (String file : files) { uploadFile(client, file); } } } catch (Exception e) { throw e; } finally { if (client != null) { client.disconnect(); } } } public boolean testFtp(OutputFtp ftp) throws Exception { FTPClient client = null; try { client = createFtpClient(ftp); changeFtpDir(client, ftp.getSavePath()); return FTPReply.isPositiveCompletion(client.getReplyCode()); } catch (Exception e) { throw e; } finally { if (client != null) { client.disconnect(); } } } private FTPClient createFtpClient(OutputFtp ftp) throws Exception { FTPClient client = new FTPClient(); client.setDataTimeout(DATA_TIME_OUT); client.setConnectTimeout(CONNECTION_TIME_OUT); client.connect(ftp.getServerAddress(), Integer.valueOf(ftp.getPort())); client.login(ftp.getUsername(), ftp.getPassword()); client.setFileType(FTPClient.BINARY_FILE_TYPE); if (FTPReply.isPositiveCompletion(client.sendCommand("OPTS UTF8", "ON"))) { client.setControlEncoding(UTF8_CHARSET); } else { client.setControlEncoding(LOCAL_CHARSET); } return client; } private void uploadFile(FTPClient client, String file) throws Exception { InputStream in = ResourceIOUtils.read(file); try { if (!client.storeFile(encodeFtpName(ResourceIOUtils.getName(file), client.getControlEncoding()), in)) { throw new Exception("upload files failed"); } } catch (Exception e) { throw e; } finally { in.close(); } } private void changeFtpDir(FTPClient client, String savePath) throws Exception { String[] parent = savePath.split("/"); if (ArrayUtils.isNotEmpty(parent)) { for (String son : parent) { if (StringUtils.isEmpty(son)) { continue; } if (!client.changeWorkingDirectory(encodeFtpName(son, client.getControlEncoding()))) { throw new Exception(":Non-existent such path: " + savePath); } } } } private String encodeFtpName(String s, String charset) throws Exception { return new String(s.getBytes(charset), SERVER_CHARSET); } }
4.注册handler和entity
OutputActionHandler.registerHandler(new FTPHandler(), OutputFtp.class.getName()); ScheduleOutputActionEntityRegister.getInstance().addClass(OutputFtpEntity.class);
【仅供内部供应商使用,不提供对外解答和培训】
3 Comments
Pioneer-沈康平
最终的entity要注册到decison平台中
Anonymous
AppMessagePushDao是怎么定义的,能发下代码吗。
Pioneer-沈康平
10.插件接口实战——FR的数据库Dao接口 可以参考这个写,定时调度这边entity注册的时候注册到decision平台中