2012-12-20 29 views
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方法中创建线程?线程总是从主方法开始,还是可以从其他方法开始?此外,这个程序将被其他人使用,所以我应该正确处理线程。他们所需要做的就是使用我的程序。所以我觉得线程逻辑不应该属于主要方法,而是listFilesForFolder这是我的程序的起点。感谢您的帮助。多线程,读取多个文件并将它们并行发送到服务器

+2

如果它是在互联网上,通常是您的瓶颈将是带宽,所以多线程可能不会有太大的帮助。线程的实际限制通常是CPU的内核数量。 – SJuan76

+0

要求是让程序多线程化。 –

+0

在这种情况下,比制作太多线程更好,我的方法将被设置为一个固定的数字(可能由一些初始化参数定义)。程序的最初部分将创建一个文件和线程列表;线程在完成上一次上传时,会从列表中获取下一个文件并上传。 – SJuan76

回答

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("")) 
+0

我正在考虑更多的执行者线。例如,当有文件要处理时,执行。这会工作吗? –

+0

你可以做各种各样的事情,只要确保你有一个混合保护列表。 – PearsonArtPhoto

+0

你的意思是互斥体?同步读取文件方法会与多线程相反吗? –

相关问题