【仅供内部供应商使用,不提供对外解答和培训】
【仅供内部供应商使用,不提供对外解答和培训】
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平台中