2012-12-20 4 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 메서드에서 스레드를 만들어야합니까? 스레드는 항상 main 메소드에서 시작 되었습니까? 아니면 다른 메소드에서 시작할 수 있습니까? 또한,이 프로그램은 다른 사람들이 사용하게 될 것이므로 쓰레드를 적절하게 처리하는 것이 제 일이되어야합니다. 그들이해야 할 일은 내 프로그램을 사용하는 것뿐입니다. 그래서 스레드 로직이 메인 메소드에 속해서는 안되며 listFilesForFolder는 내 프로그램의 시작점이라고 생각합니다. 도와 줘서 고마워.다중 스레딩, 여러 파일 읽기 및 병렬로 서버에 보내기

+2

는, 일반적으로 병목 대역폭이 될 것입니다, 그래서 멀티 스레딩은 아마 많은 도움이되지 않습니다 . 그리고 스레드의 실질적인 제한은 일반적으로 CPU의 코어 수입니다. – SJuan76

+0

요구 사항은 프로그램을 멀티 스레드로 만드는 것입니다. –

+0

그럴 경우, 너무 많은 스레드를 만드는 것보다 나은 방법은 고정 된 숫자로 설정하는 것입니다 (일부 초기화 매개 변수로 정의 할 수 있음). 프로그램의 초기 부분은 파일 및 스레드 목록을 작성합니다. 이전 업로드가 완료되면 스레드가 목록에서 다음 파일을 가져 와서 업로드합니다. – SJuan76

답변

1

대부분의 다운로드 관리자는 한 번에 최대 약 3 개의 파일을 다운로드하려고 시도합니다 (플러스 또는 마이너스 2). 나는 당신이 똑같이하는 것이 좋습니다. 기본적으로,이 (사이비 코드) 같은 것을 할 수

//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

나는 executor 라인을 더 생각하고 있었다. 예를 들어, 처리 할 파일이있는 동안 실행하십시오. 이게 효과가 있니? –

+0

여러 가지 작업을 수행 할 수 있습니다. 멀티플렉싱 보호 기능이있는 목록이 있는지 확인하십시오. – PearsonArtPhoto

+0

뮤텍스를 의미합니까? 읽기 파일 방법을 동기화하면 멀티 스레딩과 반대가됩니까? –