2
public class SOAPClient implements Runnable {

    /*
     * endpoint url, the address where soap xml will be sent. It is hard coded
     * now, later on to be made configurable
     */
    private String endpointUrl = "";
    /*
     * This is for debugging purposes Message and response are written to the
     * fileName
     */
    static String fileName = "";

    /*
     * serverResponse This is a string representation of the response received
     * from server
     */
    private String serverResponse = null;

    public String tempTestStringForDirectory = "";

    /*
     * A single file or a folder maybe provided
     */
    private File fileOrFolder;

    public SOAPClient(String endpointURL, File fileOrFolder) {
        this.endpointUrl = endpointURL;
        this.fileOrFolder = fileOrFolder;
        serverResponse = null;
    }

    /*
     * Creats a SOAPMessage out of a file that is passed
     * 
     * @param fileAddress - Contents of this file are read and a SOAPMessage is
     * created that will get sent to the server. This is a helper method. Is
     * this step (method, conversion) necessary? set tempSoapText = XML String,
     * currently getting from file, but it can be a simple string
     */
    private SOAPMessage xmlStringToSOAPMessage(String fileAddress) {
        System.out.println("xmlStringToSoap()");
        // Picking up this string from file right now
        // This can come from anywhere
        String tempSoapText = readFileToString(fileAddress);
        SOAPMessage soapMessage = null;
        try {
            // Create SoapMessage
            MessageFactory msgFactory = MessageFactory.newInstance();
            SOAPMessage message = msgFactory.createMessage();
            SOAPPart soapPart = message.getSOAPPart();
            // Load the SOAP text into a stream source
            byte[] buffer = tempSoapText.getBytes();
            ByteArrayInputStream stream = new ByteArrayInputStream(buffer);
            StreamSource source = new StreamSource(stream);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            // Set contents of message
            soapPart.setContent(source);
            message.writeTo(out);
            soapMessage = message;
        } catch (SOAPException e) {
            System.out.println("soapException xmlStringToSoap()");
            System.out.println("SOAPException : " + e);
        } catch (IOException e) {
            System.out.println("IOException xmlStringToSoap()");
            System.out.println("IOException : " + e);
        }
        return soapMessage;
    }

    /*
     * Reads the file passed and creates a string. fileAddress - Contents of
     * this file are read into a String
     */
    private String readFileToString(String fileAddress) {
        FileInputStream stream = null;
        MappedByteBuffer bb = null;
        String stringFromFile = "";
        try {
            stream = new FileInputStream(new File(fileAddress));
            FileChannel fc = stream.getChannel();
            bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
            stringFromFile = Charset.defaultCharset().decode(bb).toString();
        } catch (IOException e) {
            System.out.println("readFileToString IOException");
            e.printStackTrace();
        } finally {
            try {
                stream.close();
            } catch (IOException e) {
                System.out.println("readFileToString IOException");
                e.printStackTrace();
            }
        }
        return stringFromFile;
    }

    /*
     * soapXMLtoEndpoint sends the soapXMLFileLocation to the endpointURL
     */
    public void soapXMLtoEndpoint(String endpointURL, String soapXMLFileLocation) throws SOAPException {
        SOAPConnection connection = SOAPConnectionFactory.newInstance().createConnection();
        SOAPMessage response = connection.call(xmlStringToSOAPMessage(soapXMLFileLocation), endpointURL);
        connection.close();
        SOAPBody responseBody = response.getSOAPBody();
        SOAPBodyElement responseElement = (SOAPBodyElement) responseBody.getChildElements().next();
        SOAPElement returnElement = (SOAPElement) responseElement.getChildElements().next();
        if (responseBody.getFault() != null) {
            System.out.println("fault != null");
            System.out.println(returnElement.getValue() + " " + responseBody.getFault().getFaultString());
        } else {
            serverResponse = returnElement.getValue();
            System.out.println(serverResponse);
            System.out.println("\nfault == null, got the response properly.\n");
        }
    }

    /*
     * This is for debugging purposes. Writes string to a file.
     * 
     * @param message Contents to be written to file
     * 
     * @param fileName the name of the
     */
    private static void toFile(String message, String fileName) {
        try {
            FileWriter fstream = new FileWriter(fileName);
            System.out.println("printing to file: ".concat(fileName));
            BufferedWriter out = new BufferedWriter(fstream);
            out.write(message);
            out.close();
        } catch (Exception e) {
            System.out.println("toFile() Exception");
            System.err.println("Error: " + e.getMessage());
        }
    }

    /*
     * Using dom to parse the xml. Getting both orderID and the description.
     * 
     * @param xmlToParse XML in String format to parse. Gets the orderID and
     * description Is the error handling required? What if orderID or
     * description isn't found in the xmlToParse? Use setters and getters?
     * 
     * @param fileName only for debuggining, it can be safely removed any time.
     */
    private void domParsing(String xmlToParse, String fileName) {
        if (serverResponse == null) {
            return;
        } else {
            try {
                System.out.println("in domParsing()");
                DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
                System.out.println("serverResponse contains fault");
                Document doc = dBuilder.parse(new InputSource(new StringReader(serverResponse)));
                doc.getDocumentElement().normalize();
                NodeList orderNodeList = doc.getElementsByTagName("Order");
                if (orderNodeList.getLength() > 0) {
                    tempTestStringForDirectory = tempTestStringForDirectory + "\n Got order\n" + "\n" + fileName + "\n" + "got order\n";
                    for (int x = 0; x < orderNodeList.getLength(); x++) {
                        System.out.println(orderNodeList.item(x).getAttributes().getNamedItem("orderId").getNodeValue());
                    }
                }
                NodeList descriptionNodeList = doc.getElementsByTagName("Description");
                if (descriptionNodeList.getLength() > 0) {
                    System.out.println("getting description");
                    String tempDescriptionString = descriptionNodeList.item(0).getTextContent();
                    System.out.println(tempDescriptionString);
                    tempTestStringForDirectory = tempTestStringForDirectory + "\n Got description" + "\n" + fileName + "\n" + tempDescriptionString + "\n";
                }
            } catch (Exception e) {
                System.out.println("domParsing() Exception");
                e.printStackTrace();
            }
        }
    }

    /*
     * Reads a single file or a whole directory structure
     */
    private void listFilesForFolder(final File fileOrFolder) {
        String temp = "";
        if (fileOrFolder.isDirectory()) {
            for (final File fileEntry : fileOrFolder.listFiles()) {
                if (fileEntry.isDirectory()) {
                    listFilesForFolder(fileEntry);
                } else {
                    if (fileEntry.isFile()) {
                        temp = fileEntry.getName();
                        try {
                            soapXMLtoEndpoint(endpointUrl, fileOrFolder.getAbsolutePath() + "\\" + fileEntry.getName());
                            domParsing(serverResponse, fileEntry.getName());
                        } catch (SOAPException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        if (fileOrFolder.isFile()) {
            temp = fileOrFolder.getName();
            System.out.println("this is a file");
            System.out.println(temp);
            try {
                soapXMLtoEndpoint(endpointUrl, fileOrFolder.getAbsolutePath());
            } catch (SOAPException e) {
                e.printStackTrace();
            }
            domParsing(serverResponse, temp);
        }
    }

    @Override
    public void run() {
        listFilesForFolder(fileOrFolder);
        toFile(tempTestStringForDirectory, "test.txt");
    }

    public static void main(String[] args) {
        String tempURLString = ".../OrderingService";
        String tempFileLocation = "C:/Workspace2/Test5/";
        SOAPClient soapClient = new SOAPClient(tempURLString, new File(tempFileLocation));
        Thread thread = new Thread(soapClient);
        thread.start();
        System.out.println("program ended");
    }
}

我认为 n 个文件的 n 个线程会很糟糕?那不会使系统崩溃,或者给太多线程错误吗?我正在尝试使我的程序多线程。我不知道我错过了什么。我的程序有一个逻辑可以知道是传递了单个文件还是传递了目录。如果传递一个文件,一个线程就可以了。但是如果一个目录通过了怎么办?我需要在我的 listFilesForFolder 方法中创建线程吗?线程总是从 main 方法启动,还是可以从其他方法启动?另外,这个程序会被其他人使用,所以正确处理线程应该是我的工作。他们所要做的就是使用我的程序。所以我觉得线程逻辑不应该属于main方法,而应该属于listFilesForFolder,这是我程序的起点。

4

1 回答 1

1

据我所知,大多数下载管理器会尝试一次最多下载大约 3 个文件,正负两个。我建议你这样做。本质上,你可以做这样的事情(伪代码)

//Set up a list of objects
fileList={"a","b","c"}
nextIndex=0;
Mutex mutex
//Start_X_threads

String next_object(void){
  String nextFile;
  try{
    mutex.acquire();
    try {
        if (nextFileIndex<fileList.length)
        {
          nextFile=fileList(nextFileIndex);
          nextFileIndex++;
        }
        else
           nextFile="";
    }
    finally
    {
        mutex.release();
    }
  } catch(InterruptedException ie) {
    nextFile="";
  }
  return nextFile;
}

每个线程:

String nextFile;
do
{
   nextFile=nextObject();
   //Get nextFile
} while (!nextFile.equals(""))
于 2012-12-20T17:59:43.933 回答