SSM下整合netty使用佇列進行檔案傳輸demo
阿新 • • 發佈:2019-01-04
原創文章
自己在閒暇無事的時候做的一些小demo,在這裡分享出來給大家
@Service
@Scope("prototype")
public class PictureServiceImpl implements PictureService {
@Value("${UPLOAD_PATH}")
private String UPLOAD_PATH;
@Value("${IMAGES_URL}")
private String IMAGES_URL;
@Value("${NETTY_URL}")
private String NETTY_URL;
@Value ("${NETTY_PORT}")
private Integer NETTY_PORT;
@Autowired
private FileThreadManager fileThreadManager;
@Override
public PictureResult uploadFile(MultipartFile file) {
PictureResult pictureResult = new PictureResult();
if (!file.isEmpty()) {
try {
String fileName = file.getOriginalFilename();
String newname = UUID.randomUUID() + fileName.substring(fileName.lastIndexOf("." ));
new Thread(new Runnable() {
@Override
public void run() {
try {
fileThreadManager.start(NETTY_URL, NETTY_PORT);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
fileThreadManager.submit(file.getBytes(), newname, null );
System.out.println("嘗試獲取資料");
while (fileThreadManager.getFileInfoByName(newname) == null) {}
FileInfo fileInfo = fileThreadManager.getFileInfoByName(newname);
BeanUtils.copyProperties(fileInfo, pictureResult);
} catch (Exception e) {
e.printStackTrace();
pictureResult.setError(1);
pictureResult.setMessage("上傳失敗");
}
} else {
pictureResult.setMessage("上傳圖片為空");
pictureResult.setError(1);
}
return pictureResult;
}
}
下面是主要的佇列及netty的主要程式碼
@Component
@Scope("prototype")
public class FileThreadManager implements BeanFactoryAware{
private BeanFactory beanFactory;
private ExecutorService pool = Executors.newCachedThreadPool();
private volatile ChannelFuture cf;
private ConcurrentHashMap<String, FileInfo> map=new ConcurrentHashMap<>();
@Autowired
private CustomChannelHandler customChannelHandler;
public void submit(byte[] file,String fileNewName,String message){
while(cf==null){}
System.out.println("提交任務");
FileThread fileThread = beanFactory.getBean(FileThread.class);
fileThread.setFile(file);
fileThread.setFileNewName(fileNewName);
fileThread.setMessage(message);
fileThread.setCf(cf);
pool.execute(fileThread);
}
public void start(String nettyUrl,Integer nettyPort) throws InterruptedException{
if(cf!=null)
return ;
EventLoopGroup workgroup = new NioEventLoopGroup();
Bootstrap b = new Bootstrap();
b.group(workgroup);
b.channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
// TODO Auto-generated method stub
sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
sc.pipeline().addLast(customChannelHandler);
customChannelHandler.setMap(map);
}
});
b.option(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture cf = b.connect(nettyUrl, nettyPort).sync();
this.cf=cf;
cf.channel().closeFuture().sync();
workgroup.shutdownGracefully();
}
public FileInfo getFileInfoByName(String fileName) throws InterruptedException{
Set<Entry<String, FileInfo>> entrySet = map.entrySet();
for (Entry<String, FileInfo> entry : entrySet) {
if(entry.getKey().trim().equals(fileName.trim())){
return entry.getValue();
}
}
return null;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
// TODO Auto-generated method stub
this.beanFactory=beanFactory;
}
}
最後說一下,FileThread,FileInfo和PictureResult等類都是自己自定義的型別,根據自己的需要從而定義。