存档在 ‘java’ 分类

Apache FTPClient操作“卡死”问题的分析和解决

2017年8月16日

在部署到生产环境之后发现FTP操作不规律性出现“卡死”现象:程序捕获不到任何异常一直卡着,导致轮巡无法正常工作。

为了解决这个问题,首先考虑的是对于FTPClient的使用上没有设置超时时间,于是设置了ConnectTimeout、DataTimeout、DefaultTimeout后在生产环境上继续观察,但是问题依旧没有解决。后来我有些怀疑FTPClient api本身是不是有什么问题,想实在不行自己实现一个超时机制吧,不过还是不甘心,还是想从FTPClient api本身去解决问题。又经过一翻研究之后发现:需要使用被动模式,以下摘抄别人的一段简单描述:
在项目中使用commons-net-3.0.1.jar实现FTP文件的下载,在windows xp上运行正常,但是放到linux上,却出现问题,程序运行到 FTPClient.listFiles()或者FTPClient.retrieveFile()方法时,就停止在那里,什么反应都没有,出现假死状态。google一把,发现很多人也出现了此类问题,最终在一个帖子里找到了解决办法。在调用这两个方法之前,调用FTPClient.enterLocalPassiveMode();这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。为什么要这样做呢,因为ftp server可能每次开启不同的端口来传输数据,但是在linux上,由于安全限制,可能某些端口没有开启,所以就出现阻塞。OK,问题解决。

于是我回滚了之前的修改,改为被动模式。但是问题依旧。于是能想到的就是最有的绝招:实在不行自己实现一个超时机制吧。经过一翻研究最简单的方式就是使用:Future解决:

public static void main(String[] args) throws InterruptedException, ExecutionException {
        final ExecutorService exec = Executors.newFixedThreadPool(1);

        Callable<String> call = new Callable<String>() {
            public String call() throws Exception {
                Thread.sleep(1000 * 5);
                return "线程执行完成.";
            }
        };

        try {
            Future<String> future = exec.submit(call);
            String obj = future.get(4 * 1000, TimeUnit.MILLISECONDS); // 任务处理超时时间设置
            System.out.println("任务成功返回:" + obj);
        } catch (TimeoutException ex) {
            System.out.println("处理超时啦....");
            ex.printStackTrace();
        } catch (Exception e) {
            System.out.println("处理失败.");
            e.printStackTrace();
        }
        // 关闭线程池
        exec.shutdown();
        
        System.out.println("完毕");
    }

当然了还有很多其他方式:
http://tech.sina.com.cn/s/2008-07-04/1051720260.shtml
http://itindex.net/blog/2010/08/11/1281486125717.html
http://darkmasky.iteye.com/blog/1115047
http://www.cnblogs.com/wasp520/archive/2012/07/06/2580101.html
http://coolxing.iteye.com/blog/1476289
http://www.cnblogs.com/chenying99/archive/2012/10/24/2737924.html
虽然找到了终极的“必杀技”,但是此时我还是不甘心,还是想从FTPClient api本身去解决问题,但此时看来也别无它他法。只能试试:即设置被动模式又设置超时时间。经过实际测试,发现问题得以解决。下面把我的FTP工具类贴给大家分享,希望能帮到遇到同样问题的人。

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

public class FtpUtil {
    public static final String ANONYMOUS_LOGIN = "anonymous";
    private FTPClient ftp;
    private boolean is_connected;

    public FtpUtil() {
        ftp = new FTPClient();
        is_connected = false;
    }
    
    public FtpUtil(int defaultTimeoutSecond, int connectTimeoutSecond, int dataTimeoutSecond){
        ftp = new FTPClient();
        is_connected = false;
        
        ftp.setDefaultTimeout(defaultTimeoutSecond * 1000);
        ftp.setConnectTimeout(connectTimeoutSecond * 1000);
        ftp.setDataTimeout(dataTimeoutSecond * 1000);
    }

    /**
     * Connects to FTP server.
     * 
     * @param host
     *            FTP server address or name
     * @param port
     *            FTP server port
     * @param user
     *            user name
     * @param password
     *            user password
     * @param isTextMode
     *            text / binary mode switch
     * @throws IOException
     *             on I/O errors
     */
    public void connect(String host, int port, String user, String password, boolean isTextMode) throws IOException {
        // Connect to server.
        try {
            ftp.connect(host, port);
        } catch (UnknownHostException ex) {
            throw new IOException("Can't find FTP server '" + host + "'");
        }

        // Check rsponse after connection attempt.
        int reply = ftp.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)) {
            disconnect();
            throw new IOException("Can't connect to server '" + host + "'");
        }

        if (user == "") {
            user = ANONYMOUS_LOGIN;
        }

        // Login.
        if (!ftp.login(user, password)) {
            is_connected = false;
            disconnect();
            throw new IOException("Can't login to server '" + host + "'");
        } else {
            is_connected = true;
        }

        // Set data transfer mode.
        if (isTextMode) {
            ftp.setFileType(FTP.ASCII_FILE_TYPE);
        } else {
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
        }
    }

    /**
     * Uploads the file to the FTP server.
     * 
     * @param ftpFileName
     *            server file name (with absolute path)
     * @param localFile
     *            local file to upload
     * @throws IOException
     *             on I/O errors
     */
    public void upload(String ftpFileName, File localFile) throws IOException {
        // File check.
        if (!localFile.exists()) {
            throw new IOException("Can't upload '" + localFile.getAbsolutePath() + "'. This file doesn't exist.");
        }

        // Upload.
        InputStream in = null;
        try {

            // Use passive mode to pass firewalls.
            ftp.enterLocalPassiveMode();

            in = new BufferedInputStream(new FileInputStream(localFile));
            if (!ftp.storeFile(ftpFileName, in)) {
                throw new IOException("Can't upload file '" + ftpFileName + "' to FTP server. Check FTP permissions and path.");
            }

        } finally {
            try {
                in.close();
            } catch (IOException ex) {
            }
        }
    }

    /**
     * Downloads the file from the FTP server.
     * 
     * @param ftpFileName
     *            server file name (with absolute path)
     * @param localFile
     *            local file to download into
     * @throws IOException
     *             on I/O errors
     */
    public void download(String ftpFileName, File localFile) throws IOException {
        // Download.
        OutputStream out = null;
        try {
            // Use passive mode to pass firewalls.
            ftp.enterLocalPassiveMode();

            // Get file info.
            FTPFile[] fileInfoArray = ftp.listFiles(ftpFileName);
            if (fileInfoArray == null) {
                throw new FileNotFoundException("File " + ftpFileName + " was not found on FTP server.");
            }

            // Check file size.
            FTPFile fileInfo = fileInfoArray[0];
            long size = fileInfo.getSize();
            if (size > Integer.MAX_VALUE) {
                throw new IOException("File " + ftpFileName + " is too large.");
            }

            // Download file.
            out = new BufferedOutputStream(new FileOutputStream(localFile));
            if (!ftp.retrieveFile(ftpFileName, out)) {
                throw new IOException("Error loading file " + ftpFileName + " from FTP server. Check FTP permissions and path.");
            }

            out.flush();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException ex) {
                }
            }
        }
    }

    /**
     * Removes the file from the FTP server.
     * 
     * @param ftpFileName
     *            server file name (with absolute path)
     * @throws IOException
     *             on I/O errors
     */
    public void remove(String ftpFileName) throws IOException {
        if (!ftp.deleteFile(ftpFileName)) {
            throw new IOException("Can't remove file '" + ftpFileName + "' from FTP server.");
        }
    }

    /**
     * Lists the files in the given FTP directory.
     * 
     * @param filePath
     *            absolute path on the server
     * @return files relative names list
     * @throws IOException
     *             on I/O errors
     */
    public List<String> list(String filePath) throws IOException {
        List<String> fileList = new ArrayList<String>();
        
        // Use passive mode to pass firewalls.
        ftp.enterLocalPassiveMode();
        
        FTPFile[] ftpFiles = ftp.listFiles(filePath);
        int size = (ftpFiles == null) ? 0 : ftpFiles.length;
        for (int i = 0; i < size; i++) {
            FTPFile ftpFile = ftpFiles[i];
            if (ftpFile.isFile()) {
                fileList.add(ftpFile.getName());
            }
        }
        
        return fileList;
    }

    /**
     * Sends an FTP Server site specific command
     * 
     * @param args
     *            site command arguments
     * @throws IOException
     *             on I/O errors
     */
    public void sendSiteCommand(String args) throws IOException {
        if (ftp.isConnected()) {
            try {
                ftp.sendSiteCommand(args);
            } catch (IOException ex) {
            }
        }
    }

    /**
     * Disconnects from the FTP server
     * 
     * @throws IOException
     *             on I/O errors
     */
    public void disconnect() throws IOException {

        if (ftp.isConnected()) {
            try {
                ftp.logout();
                ftp.disconnect();
                is_connected = false;
            } catch (IOException ex) {
            }
        }
    }

    /**
     * Makes the full name of the file on the FTP server by joining its path and
     * the local file name.
     * 
     * @param ftpPath
     *            file path on the server
     * @param localFile
     *            local file
     * @return full name of the file on the FTP server
     */
    public String makeFTPFileName(String ftpPath, File localFile) {
        if (ftpPath == "") {
            return localFile.getName();
        } else {
            String path = ftpPath.trim();
            if (path.charAt(path.length() - 1) != '/') {
                path = path + "/";
            }

            return path + localFile.getName();
        }
    }

    /**
     * Test coonection to ftp server
     * 
     * @return true, if connected
     */
    public boolean isConnected() {
        return is_connected;
    }

    /**
     * Get current directory on ftp server
     * 
     * @return current directory
     */
    public String getWorkingDirectory() {
        if (!is_connected) {
            return "";
        }

        try {
            return ftp.printWorkingDirectory();
        } catch (IOException e) {
        }

        return "";
    }

    /**
     * Set working directory on ftp server
     * 
     * @param dir
     *            new working directory
     * @return true, if working directory changed
     */
    public boolean setWorkingDirectory(String dir) {
        if (!is_connected) {
            return false;
        }

        try {
            return ftp.changeWorkingDirectory(dir);
        } catch (IOException e) {
        }

        return false;
    }

    /**
     * Change working directory on ftp server to parent directory
     * 
     * @return true, if working directory changed
     */
    public boolean setParentDirectory() {
        if (!is_connected) {
            return false;
        }

        try {
            return ftp.changeToParentDirectory();
        } catch (IOException e) {
        }

        return false;
    }

    /**
     * Get parent directory name on ftp server
     * 
     * @return parent directory
     */
    public String getParentDirectory() {
        if (!is_connected) {
            return "";
        }

        String w = getWorkingDirectory();
        setParentDirectory();
        String p = getWorkingDirectory();
        setWorkingDirectory(w);

        return p;
    }

    /**
     * Get directory contents on ftp server
     * 
     * @param filePath
     *            directory
     * @return list of FTPFileInfo structures
     * @throws IOException
     */
    public List<FfpFileInfo> listFiles(String filePath) throws IOException {
        List<FfpFileInfo> fileList = new ArrayList<FfpFileInfo>();
        
        // Use passive mode to pass firewalls.
        ftp.enterLocalPassiveMode();
        FTPFile[] ftpFiles = ftp.listFiles(filePath);
        int size = (ftpFiles == null) ? 0 : ftpFiles.length;
        for (int i = 0; i < size; i++) {
            FTPFile ftpFile = ftpFiles[i];
            FfpFileInfo fi = new FfpFileInfo();
            fi.setName(ftpFile.getName());
            fi.setSize(ftpFile.getSize());
            fi.setTimestamp(ftpFile.getTimestamp());
            fi.setType(ftpFile.isDirectory());
            fileList.add(fi);
        }

        return fileList;
    }

    /**
     * Get file from ftp server into given output stream
     * 
     * @param ftpFileName
     *            file name on ftp server
     * @param out
     *            OutputStream
     * @throws IOException
     */
    public void getFile(String ftpFileName, OutputStream out) throws IOException {
        try {
            // Use passive mode to pass firewalls.
            ftp.enterLocalPassiveMode();
            
            // Get file info.
            FTPFile[] fileInfoArray = ftp.listFiles(ftpFileName);
            if (fileInfoArray == null) {
                throw new FileNotFoundException("File '" + ftpFileName + "' was not found on FTP server.");
            }

            // Check file size.
            FTPFile fileInfo = fileInfoArray[0];
            long size = fileInfo.getSize();
            if (size > Integer.MAX_VALUE) {
                throw new IOException("File '" + ftpFileName + "' is too large.");
            }

            // Download file.
            if (!ftp.retrieveFile(ftpFileName, out)) {
                throw new IOException("Error loading file '" + ftpFileName + "' from FTP server. Check FTP permissions and path.");
            }

            out.flush();

        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException ex) {
                }
            }
        }
    }

    /**
     * Put file on ftp server from given input stream
     * 
     * @param ftpFileName
     *            file name on ftp server
     * @param in
     *            InputStream
     * @throws IOException
     */
    public void putFile(String ftpFileName, InputStream in) throws IOException {
        try {
            // Use passive mode to pass firewalls.
            ftp.enterLocalPassiveMode();
            
            if (!ftp.storeFile(ftpFileName, in)) {
                throw new IOException("Can't upload file '" + ftpFileName + "' to FTP server. Check FTP permissions and path.");
            }
        } finally {
            try {
                in.close();
            } catch (IOException ex) {
            }
        }
    }
}

commons2.0FTP组件开发上传时间过长程序假死解决方案

2017年8月14日

最近使用apache上面的commons 2.0开发ftp使用过程中,因为涉及到大文件的长时间传输,在最后经常导致程序死掉。其中传文件的代码如下:

/** 
 * 上传文件到服务器,新上传和断点续传 
 * @param remoteFile 远程文件名,在上传之前已经将服务器工作目录做了改变 
 * @param localFile 本地文件File句柄,绝对路径 
 * @param processStep 需要显示的处理进度步进值 
 * @param ftpClient FTPClient引用 
 * @return 
 * @throws IOException 
 */  
public boolean uploadFile(String remoteFile,File localFile,FTPClient ftpClient,long remoteSize) throws IOException{  
    boolean status;  
    //显示进度的上传  
    long step = localFile.length() / 100;  
    long process = 0;  
    long localreadbytes = 0L;  
    RandomAccessFile raf = new RandomAccessFile(localFile,"r");  
    OutputStream out = ftpClient.appendFileStream(new String(remoteFile.getBytes("GBK"),"iso-8859-1"));  
    //断点续传设置起始位置  
    if(remoteSize>0){  
        ftpClient.setRestartOffset(remoteSize);  
        process = remoteSize /step;  
        raf.seek(remoteSize);  
        localreadbytes = remoteSize;  
    }  
    byte[] bytes = new byte[1024];  
    int c;  
    //开始上传  
    while((c = raf.read(bytes))!= -1){  
        out.write(bytes,0,c);  
        localreadbytes+=c;  
        if(localreadbytes / step != process){  
            process = localreadbytes / step;  
//          System.out.println("上传进度:" + process);  
            //TODO 添加汇报上传状态内容  
        }  
    }  
    logger.info("清空输出流");  
    out.flush();  
    logger.info("关闭文件读句柄");  
    raf.close();  
    logger.info("关闭输出流");  
    out.close();  
    logger.info("关闭输出流成功");  
    boolean status = ftpClient.completePendingCommand();  
    logger.info("从上传方法返回");  
    return status;  
}  

如果上传大的文件,比如说是500M文件,ftp传输大概需要两个小时左右的时候,ftpClient.completePendingCommand()方法就会死掉,我在网上也查了一些内容,说是打开的流必须关闭后ftp Server才会返回正确的状态吗。问题是我关闭了同样没有收到正确的状态码。

如果换成appendFile(String remoteFile,InputStream in)这种方法就不会存在问题,

问题在于completePendingCommand()方法始终不能返回,介绍一下我在调试过程中遇到的问题。
1.FTP服务器有控制连接和数据连接,我的猜测是在进行数据传输的过程中,数据连接一直工作,但是控制连接可能就处于空闲状态,造成被服务器主动关闭,因此不能正常返回。
2.在网上也看了一些网友的介绍,说在调用completePendingCommand()方法时必须关闭输入输出流,而调用这个方法主要就是为了拿到服务器端的226相应(File OK)。
3.我的方法再调用completePendingCommand()方法时,输入输出流确实已经关闭,所以上诉的第2点不适合我的程序。
4.另外我对程序进行更改,不调用completePendingCommand()方法,直接返回 后,发现在后续的程序中,如果发送命令(如PASV)到服务器端,收到的响应为226 File receive OK.而后续的基本上都正常了。

综合以上分析我采用如下的方法来处理:
在关闭输入输出流后发送NOOP命令激活控制连接,然后调用completePendingCommand()方法返回。
现在我测试的结果是,即使数据传输3个小时,也不会造成程序假死。

while((c = raf.read(bytes))!= -1){  
    out.write(bytes,0,c);  
    localreadbytes+=c;  
    if(localreadbytes / step != process){  
        process = localreadbytes / step;  
//      System.out.println("上传进度:" + process);  
        //汇报上传状态,汇报进度函数,自己实现  
        reportUploadPercent((int)process);  
    }  
    out.flush();  
}  
raf.close();  
out.close();  
ftpClient.sendNoOp();  
boolean result = ftpClient.completePendingCommand();  

用Apache commons-net 包对服务器上的文件进行先重写后删除操作

2017年3月28日

为了确保安全,在删除ftp服务器上文件之前需要用1k大小的随机数重写该文件。
该操作需要用到Apache commons-net 包下面的FTPClient类,为了重写文件,我用到了该类的storeFileStream(String remote)方法,该方法返回一个OutputStream,起初没注意到OutputStream的flush和close方法就调用FTPClient类的deleteFile方法,如果该方法运行成功则返回true,但是碰到了一个奇怪的现象,deleteFile方法返回了true并没有删除文件。CSDN的网友告诉我可能是因为有文件打开着,并没有删除成功。
后来我调用了OutputStream的flush和close方法。读写第一个文件时总是正确的,当相同API读写第二个文件时,block住了。好友海波提醒了我storeFileStream(String remote)方法因为不能马上处理流,所以需要用户手工调用completePendingCommand。FTPClient要求在进行流操作之后执行completePendingCommand,以确保流处理完毕,因为流处理不是即时的,所以也没有办法手工调用completePendingCommand。于是改用public boolean storeFile(String remote, InputStream local)方法,成功解决该问题。

参考文献:http://bbs.csdn.net/topics/350033818
http://www.cnblogs.com/xiangpiaopiao2011/archive/2012/02/28/2371679.html

java.lang.RuntimeException: Can not create instance of class: demo.DemoConfig

2017年3月24日

WARN:oejuc.AbstractLifeCycle:FAILED jfinal: java.lang.RuntimeException: Can not create instance of class: demo.DemoConfig. Please check the config in web.xml
java.lang.RuntimeException: Can not create instance of class: demo.DemoConfig. Please check the config in web.xml
at com.jfinal.core.JFinalFilter.createJFinalConfig(JFinalFilter.java:104)
at com.jfinal.core.JFinalFilter.init(JFinalFilter.java:47)
at org.eclipse.jetty.servlet.FilterHolder.doStart(FilterHolder.java:119)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:724)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:265)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:706)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:492)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:95)
at org.eclipse.jetty.server.Server.doStart(Server.java:277)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
at com.jfinal.server.JettyServer.doStart(JettyServer.java:120)
at com.jfinal.server.JettyServer.start(JettyServer.java:64)
at com.jfinal.core.JFinal.start(JFinal.java:159)
at demo.DemoConfig.main(DemoConfig.java:33)
2017-03-13 22:29:17.503:WARN:oejw.WebAppContext:Failed startup of context o.e.j.w.WebAppContext{/,file:/D:/extend/workspace/example/WebRoot/}
java.lang.RuntimeException: Can not create instance of class: demo.DemoConfig. Please check the config in web.xml
at com.jfinal.core.JFinalFilter.createJFinalConfig(JFinalFilter.java:104)
at com.jfinal.core.JFinalFilter.init(JFinalFilter.java:47)
at org.eclipse.jetty.servlet.FilterHolder.doStart(FilterHolder.java:119)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:724)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:265)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:706)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:492)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:95)
at org.eclipse.jetty.server.Server.doStart(Server.java:277)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
at com.jfinal.server.JettyServer.doStart(JettyServer.java:120)
at com.jfinal.server.JettyServer.start(JettyServer.java:64)
at com.jfinal.core.JFinal.start(JFinal.java:159)
at demo.DemoConfig.main(DemoConfig.java:33)
Starting Complete. Welcome To The JFinal World :)

需设置编译的 class 文件输出路径需要设置为 WEB-INF/classes
093250_ThPl_201137

java历史版本下载地址

2017年3月24日

The Oracle Java Archive offers self-service download access to some of our historical Java releases.

WARNING: These older versions of the JRE and JDK are provided to help developers debug issues in older systems. They are not updated with the latest security patches and are not recommended for use in production.

For production use Oracle recommends downloading the latest JDK and JRE versions and allowing auto-update.

Only developers and Enterprise administrators should download these releases.

Downloading these releases requires an oracle.com account. If you don’t have an oracle.com account you can use the links on the top of this page to learn more about it and register for one for free.

For current Java releases, please consult the Oracle Software Download page.

Current update releases for JDK 6 and JDK 7 are available for support customers.  If you already have a support contract see support note 1412103.2  To learn more about Oracle Java SE Support visit our Java SE Products Page.

For more information on the transition of products from the legacy Sun download system to the Oracle Technology Network, visit the SDLC Decommission page announcement.

Java SE

Download Java SE 8

Download Java SE 7

Download Java SE 6

Download Java SE 5

Download Java SE 1.4

Download Java SE 1.3

Download Java SE 1.2

Download Java SE 1.1

Download JRockit Family

Download Java SE Tutorials

Download JDK 1.3 Documentation

Download JDK 1.4.2 Documentation

 

http://www.oracle.com/technetwork/java/archive-139210.html

Eclipse导入git上的maven web项目 部署

2017年3月23日

(1) Eclipse中从github导入maven项目 参考可以得到一个maven项目

(2) 使用Eclipse构建Maven的Web项目 参考2.3节
(3)http://www.cnblogs.com/lpshou/p/3199243.html

Java String.split()用法小结

2017年3月1日

在java.lang包中有String.split()方法,返回是一个数组

我在应用中用到一些,给大家总结一下,仅供大家参考:

1、如果用“.”作为分隔的话,必须是如下写法,String.split(“\\.”),这样才能正确的分隔开,不能用String.split(“.”);

2、如果用“|”作为分隔的话,必须是如下写法,String.split(“\\|”),这样才能正确的分隔开,不能用String.split(“|”);

“.”和“|”都是转义字符,必须得加”\\”;

3、如果在一个字符串中有多个分隔符,可以用“|”作为连字符,比如,“acount=? and uu =? or n=?”,把三个都分隔出来,可以用String.split(“and|or”);

maven项目No goals have been specified for this build.

2016年8月15日

maven项目编译说明:
未用maven前对于普通的java工程,我们如果修改了.java或配置文件,只要他在classes下,只须保存下,eclipse就会编译到bin文件夹下。
使用maven后,一般修改了.java或配置文件, eclipse也会帮我们编译到target/classes下。
但如果你使用了pom.xml下的properties值来替换配置文件里的${},并只修改了pom.xml里的properties的值,那么eclipse是不会帮我们编译的。
还需我们手工编译,方法一使用eclipse maven插件,选择run as maven build…,在goals里输入compile(maven 编译),这样它才会使用maven编译,如果想要生成可执行jar包,需要在goals中输入package
把参数设置到配置文件里。方法二使用maven命令,控制台进入当前工程文件夹,执行mvn compile.或者 maven package。