这段代码如何重构

问题描述

有类似这么个代码:FTPClient fc = new FTPClient();try {fc.connect("127.0.0.1");} catch (SocketException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}//略去其他在我程序中有类似大量这种try、catch出现,而且每次都要判断一下,如果没有异常就返回true,如果有异常就返回false,同时大多是这种fc.connect("127.0.0.1"),返回的是void类型的,本来想写个方法如:public static boolean xxx(void obj){里面是try、catch和判断},然后调用如:Test.xxx(fc.connect("127.0.0.1")),然后如果连接成功则返回true,失败则返回false,最后我再根据结果做相应业务处理。但是参数类型是不能为void的,那么该如何是好啊?如果每次都是try、catch及大量boolean判断,整个代码将相当冗余及逻辑混乱。 问题补充:大家可能没明白我的意思,都怪我,应该贴出全部代码的。其要求如下:1、都要捕获异常,以便将来日志记录(坑爹的要求。。。还没完成)2、connection连接失败,则再连3次,失败则结束,返回false,成功则继续3、登录失败,处理异常并断开连接,成功继续4、在服务端找不到要下载的文件,处理异常,并且关闭连接返回重新连接3次(坑爹的要求。。。还没完成),3次后还不行则返回false,正常则下好结束,关闭代码如下:package com.jftt.util;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.net.SocketException;import org.apache.commons.net.ftp.FTPClient;import org.apache.commons.net.ftp.FTPFile;import org.apache.commons.net.ftp.FTPReply;public class DownLoadUtil {/** * Description: 从FTP服务器下载文件 * @author hebin * @param url FTP服务器hostname * @param port FTP服务器端口 * @param connectionTimes 连接次数 * @param timeOut 等待时间 * @param username FTP登录账号 * @param password FTP登录密码 * @param remotePath FTP服务器上的相对路径 * @param fileName 要下载的文件名 * @param localPath 下载后保存到本地的路径 * @return success */public static boolean downFile(String url,int port,int connectionTimes,int timeOut,String username,String password,String remotePath,String fileName, String localPath){//初始化,默认连接成功boolean success = true; //创建ftp客户端FTPClient ftp = new FTPClient();//定义失败后的连接次数为3for (int i = 0; i < connectionTimes; i++) {try {//通过url和端口号连接ftp服务器ftp.connect(url, port);System.out.println("连接成功");success = true; i = connectionTimes + 1;//成功连接则跳出for循环,失败则继续执行for循环break;} catch (SocketException e) {e.printStackTrace();System.out.println("连接失败");} catch (IOException e) {e.printStackTrace();System.out.println("连接失败");}try {//10秒未连上则中断连接Thread.sleep(timeOut);} catch (InterruptedException e) {success=false;e.printStackTrace();}}try {ftp.login(username, password);System.out.println("登录成功");success = true; } catch (IOException e) {e.printStackTrace();System.out.println("登录失败");success = false;try {ftp.logout();ftp.disconnect();} catch (IOException e1) {System.out.println("关闭失败");e1.printStackTrace();}}int reply = 0; reply = ftp.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { try {ftp.disconnect();success = true;} catch (IOException e) {e.printStackTrace();success = false;} return success; } try {ftp.changeWorkingDirectory(remotePath);} catch (IOException e) {e.printStackTrace();}FTPFile[] fs;try {fs = ftp.listFiles();for(FTPFile ff:fs){ String path = remotePath + HandleFileNameUtil.handleFileName(fileName);//判断是否是主服务器文件路径if(ff.getName().equals(path)){ //经过处理后的文件名File localFile = new File(localPath+"/"+HandleFileNameUtil.handleFileName(fileName)); OutputStream is = new FileOutputStream(localFile); ftp.retrieveFile(ff.getName(),is); is.close();ftp.logout();ftp.disconnect();success = true;break;}else{success = false;} } } catch (IOException e) {System.out.println("文件不存在");e.printStackTrace();success = false; }return success; }}

解决方案

其实楼上都说的是异常处理办法,给你一段代码:public class DownLoadUtil {public static FTPClient open(String url, int port, int connectionTimes, int timeOut, String username, String password) throws IOException {FTPClient ftp = new FTPClient();ftp.setConnectTimeout(timeOut);for (int i = 1;; i++) {try {ftp.connect(url, port);ftp.login(username, password);return ftp;} catch (IOException e) {if (i >= connectionTimes) throw e;}}}public static void close(FTPClient ftp) {if (ftp != null) {try {ftp.disconnect();} catch (IOException e) {}}}public static void downFile(String url, int port, int connectionTimes, int timeOut, String username,String password, String remotePath, String fileName, String localPath) throws IOException {FTPClient ftp = null;try {ftp = open(url, port, connectionTimes, timeOut, username, password);ftp.changeWorkingDirectory(remotePath);FTPFile[] fs = ftp.listFiles();for (FTPFile ff : fs) {String path = remotePath + HandleFileNameUtil.handleFileName(fileName);// 判断是否是主服务器文件路径if (ff.getName().equals(path)) {// 经过处理后的文件名File localFile = new File(localPath + "/" + HandleFileNameUtil.handleFileName(fileName));try (OutputStream is = new FileOutputStream(localFile)) {ftp.retrieveFile(ff.getName(), is);}}}} finally {close(ftp);}}}
解决方案二:
可以把异常抛出去,在上一层调用时,统一处理这样做就是不知道具体是那个处理上抛出了异常,提示信息不好打...
解决方案三:
如果你使用的是JDK7,可以考如下建议:1)如果确实应该捕获这些异常,并且两个异常处理方式都是相同的,可以使用Java7新加入的语法来处理: catch(SocketException|IOException e) { //处理代码 }2)其实实际使用的过程中应该还有另外一个问题,就是需要处理的finally块, 比如 catch(SocketException|IOException e) { //处理代码 } finally { if(client!=null) { client.close(); } } 这个可以使你FTPClient实现AutoCloseable接口,这样就省去finally里面的麻烦了(finally里面的代码不做的话,有可能会造成连接泄露)。这个也是Java7里面的功能。
解决方案四:
你这异常抓的一点意义都没有 你可能天天看着后台或者天天看着日志去吗出现异常要么自行处理掉 要么 抛给上层调用者针对用户操作层抛出的异常 那么必须给予用户提示
解决方案五:
(1)如果出现SocketException,IOException的时候处理都是e.printStackTrace(),那应该就不用分开捕获了异常,没有实际意义;(2)Test.xxx(fc.connect("127.0.0.1")),这样写同样需要捕获异常,是不是可以考虑把fc.connect("127.0.0.1")放到Test.xxx方法的声明里,出现异常返回false,无异常返回true;(3)常是否异往上抛可能决定于你对fc.coct("127.0.nne0.1")的错误处理机制,如果出现这种错误不需要继续运行后续代码,那么可以考虑直接向上抛出,如果向上抛出的异常类型对你的业务逻辑没有意义的话可以在Test.xxx方法中把异常转换为RuntimeException,可能方法的签名会简洁清晰一点。
解决方案六:
public static boolean connect(FTPClient fc, String ip) throws Exception{ fc.connect("127.0.0.1"); 交给要调用的地方处理,如果调用的地方,连接都出了异常,就直接不用调用别的方法了
解决方案七:
如果不想太多catch语句块,你可以向上层抛,然后在最外层根据Exception的种类,进行不同的处理。
解决方案八:
把上面的代码段放到一个方法中,如:public static boolean connect(FTPClient fc, String ip) { try {fc.connect("127.0.0.1"); return true; } catch (SocketException e) {e.printStackTrace(); } catch (IOException e) {e.printStackTrace(); } catch (NullPointerException npe) { npe.printStackTrace(); } return false;}上面代码块的缺点就是不知道发生了何种异常。建议你自定义一个异常类,然后设置异常编码,把上面可能发生的异常定义成相应的编码,然后抛到上层
解决方案:
异常上抛

时间: 2024-09-03 13:41:00

这段代码如何重构的相关文章

javascript-本人刚入门js,请问像如下的这段代码大致该怎么重构

问题描述 本人刚入门js,请问像如下的这段代码大致该怎么重构 var prepareCart = function (host, accessToken, username, state, count,filename) { if (count == 0) { completeTest(state); } else { log("INFO", "Preparing the cart"); request.post({ url: host + '/ls/api/tes

二叉树 二叉树重构-这段代码有哪里会引起RuntimeError的地方么

问题描述 这段代码有哪里会引起RuntimeError的地方么 我在本地测试没出过问题,但是放到oj系统上就runtime error,错误代码11. 应该是访问到未定义的内存,可是我查了好久都没找到哪里越界了,求指教 #include <cstdio> #pragma warning(disable:4996) class TreeNode { public: int data; TreeNode* fo; TreeNode* ba; }; class Tree { public: int

浅谈遗留代码的重构

             背景 <重构>诞生至今有近17个年头了,日常开发中大家谈到重构,要么非常随意,认为重构就是改代码:要么非常谨慎,把重构描述成焦油坑,像瘟神一样敬而远之.针对最具挑战性的遗留代码重构,有哪些需要注意的呢? 谈论任何事情,都该有它的上下文.本文谈论的技术背景是大型通信类产品,对于互联网产品不一定适用.另外,本文也不会涉及重构技术,有兴趣读者可以读<重构>或者<Effective Refactoring in C++>. 遗留代码重构决策表 遗留代码

方法-c#2010里怎么设置一段代码的属性??新人求解

问题描述 c#2010里怎么设置一段代码的属性??新人求解 这是我在网上找的用C写坦克大站的一段代码,教程视频里作者在 p1Tank上按了不知道什么键然后弹出一个窗口确认后就出现了下面这几行代码,我却找不到方法. private P1Tank p1Tank; public P1Tank P1Tank { get { return p1Tank; } set { p1Tank = value; } } 解决方案 这个是封装 pubice p1Tank p1tank: 选中后面的p1tank然后右键

c++-这段代码怎么改,才能运行(main的第一行要保留)

问题描述 这段代码怎么改,才能运行(main的第一行要保留) #include using namespace std; class student { public: student(int n,float s):num(n),score(s){} void change(int n,float s){num=n;score=s;} void display(){cout<<num<<" "<<score<<endl;} private

孙鑫-Visual C++的一段代码搞不懂求解释

问题描述 Visual C++的一段代码搞不懂求解释 说一下自己的理解.题目是孙鑫老是的文本输出的例子. 1:GetBkColor得到背景白色,然后SetTextColor(白色)把背景白色设置为文字颜色.跟着clr应该是赋值得到白色了吧,但是F5看的时候是黑色,就要原文字颜色.我这么理解应该错了 1 COLORREF clr=dc.SetTextColor(dc.GetBkColor()); //GetBkColor属于dc对象,改变dc中的背景值(白色).然后SetTextColor用白色值

android-贴一段代码,关于自动接听的,请老司机帮帮忙

问题描述 贴一段代码,关于自动接听的,请老司机帮帮忙 public synchronized void answerRingingCall(Context context) { try { Log.e("try to answer", "below 2.3"); //ITelephony itelephony = getITelephony(mTelephonyManager); Method method = Class.forName("android

编译错误-出现了fatal exception :main 这是其中的一段代码,大家看看有什么问题

问题描述 出现了fatal exception :main 这是其中的一段代码,大家看看有什么问题 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); loginBtn = (Button)findViewById(R.id.login_btn_login); registerBtn = (Butt

求助servlet 这段代码什么意思

问题描述 求助servlet 这段代码什么意思 */ @RequestMapping("/getTile.do") public @ResponseBody String getTile(HttpServletResponse response, @RequestParam(value = "map_id", required = true) String mapId, @RequestParam(required = true) int level, @Reque