0

我正在学习java课程并遇到了这个问题:尝试制作基于XML的客户端-服务器通信协议(使用XMLStreamReader/Writer)

服务器:

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;


public class ServerMain extends Thread {
    private ServerSocket server;

    public ServerMain(String bindAddr) throws Exception {
        this.server = new ServerSocket(61792, 1, InetAddress.getByName(bindAddr));
    }

    private void listen() throws Exception {
        while (true) {
            System.out.println("READY TO CONNECTION. STAND-BY");
            Socket client = this.server.accept();
            String clientAddress = client.getInetAddress().getHostAddress();
            System.out.println("\nCLIENT CONNECTED! ip = " + clientAddress);

            XMLInputFactory xmlif = XMLInputFactory.newInstance();
            Reader fileReader = new InputStreamReader(client.getInputStream());
            XMLStreamReader xmlr = xmlif.createXMLStreamReader(fileReader);

            while (xmlr.hasNext()) {
                printEvent(xmlr);
                xmlr.next();
            }
            System.out.println("ENDDDDDDDDDDDDDDDDDDDDDD");
            xmlr.close();
        }
    }


    private static void printEvent(XMLStreamReader xmlr) {
        System.out.print("EVENT:["+xmlr.getLocation().getLineNumber()+"]["+
                xmlr.getLocation().getColumnNumber()+"] ");
        System.out.print(" [");
        switch (xmlr.getEventType()) {
            case XMLStreamConstants.START_ELEMENT:
                System.out.print("<");
                printName(xmlr);
                printNamespaces(xmlr);
                printAttributes(xmlr);
                System.out.print(">");
                break;
            case XMLStreamConstants.END_ELEMENT:
                System.out.print("</");
                printName(xmlr);
                System.out.print(">");
                break;
            case XMLStreamConstants.SPACE:
            case XMLStreamConstants.CHARACTERS:
                int start = xmlr.getTextStart();
                int length = xmlr.getTextLength();
                System.out.print(new String(xmlr.getTextCharacters(),
                        start,
                        length));
                break;
            case XMLStreamConstants.PROCESSING_INSTRUCTION:
                System.out.print("<?");
                if (xmlr.hasText())
                    System.out.print(xmlr.getText());
                System.out.print("?>");
                break;
            case XMLStreamConstants.CDATA:
                System.out.print("<![CDATA[");
                start = xmlr.getTextStart();
                length = xmlr.getTextLength();
                System.out.print(new String(xmlr.getTextCharacters(),
                        start,
                        length));
                System.out.print("]]>");
                break;
            case XMLStreamConstants.COMMENT:
                System.out.print("<!--");
                if (xmlr.hasText())
                    System.out.print(xmlr.getText());
                System.out.print("-->");
                break;
            case XMLStreamConstants.ENTITY_REFERENCE:
                System.out.print(xmlr.getLocalName()+"=");
                if (xmlr.hasText())
                    System.out.print("["+xmlr.getText()+"]");
                break;
            case XMLStreamConstants.START_DOCUMENT:
                System.out.print("<?xml");
                System.out.print(" version='"+xmlr.getVersion()+"'");
                System.out.print(" encoding='"+xmlr.getCharacterEncodingScheme()+"'");
                if (xmlr.isStandalone())
                    System.out.print(" standalone='yes'");
                else
                    System.out.print(" standalone='no'");
                System.out.print("?>");
                break;
            case XMLStreamConstants.END_DOCUMENT:
                System.out.print("</END");
                printName(xmlr);
                System.out.print("END>");
                break;
        }
        System.out.println("]");
    }

    private static void printName(XMLStreamReader xmlr){
        if(xmlr.hasName()){
            String prefix = xmlr.getPrefix();
            String uri = xmlr.getNamespaceURI();
            String localName = xmlr.getLocalName();
            printName(prefix,uri,localName);
        }
    }
    private static void printName(String prefix,
                                  String uri,
                                  String localName) {
        if (uri != null && !("".equals(uri)) ) System.out.print("['"+uri+"']:");
        if (prefix != null) System.out.print(prefix+":");
        if (localName != null) System.out.print(localName);
    }
    private static void printAttributes(XMLStreamReader xmlr){
        for (int i=0; i < xmlr.getAttributeCount(); i++) {
            printAttribute(xmlr,i);
        }
    }
    private static void printAttribute(XMLStreamReader xmlr, int index) {
        String prefix = xmlr.getAttributePrefix(index);
        String namespace = xmlr.getAttributeNamespace(index);
        String localName = xmlr.getAttributeLocalName(index);
        String value = xmlr.getAttributeValue(index);
        System.out.print(" ");
        printName(prefix,namespace,localName);
        System.out.print("='"+value+"'");
    }
    private static void printNamespaces(XMLStreamReader xmlr){
        for (int i=0; i < xmlr.getNamespaceCount(); i++) {
            printNamespace(xmlr,i);
        }
    }
    private static void printNamespace(XMLStreamReader xmlr, int index) {
        String prefix = xmlr.getNamespacePrefix(index);
        String uri = xmlr.getNamespaceURI(index);
        System.out.print(" ");
        if (prefix == null)
            System.out.print("xmlns='"+uri+"'");
        else
            System.out.print("xmlns:"+prefix+"='"+uri+"'");
    }


    public InetAddress getSocketAddress() {
        return this.server.getInetAddress();
    }

    public int getPort() {
        return this.server.getLocalPort();
    }

    public static void main(String[] args) throws Exception {
        ServerMain app = new ServerMain("localhost");

        System.out.println("\r\nRunning Server: " +
                "Host=" + app.getSocketAddress().getHostAddress() +
                " Port=" + app.getPort());

        app.listen();
    }
}

客户:

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;

public class ClientMain {
    private Socket socket;
    private Scanner scanner;

    private ClientMain(InetAddress serverAddress, int serverPort) throws Exception {
        this.socket = new Socket(serverAddress, serverPort);
        this.scanner = new Scanner(System.in);
    }

    public static void main(String[] args) throws Exception {
        ClientMain client = new ClientMain(InetAddress.getByName("localhost"), 61792);

        System.out.println("\nConnected to: " + client.socket.getInetAddress());
        System.out.println("ENTER SOMETHING: ");
        client.start();
    }

    private void start() throws IOException, XMLStreamException {
        String input;
        XMLOutputFactory factory = XMLOutputFactory.newInstance();
        XMLStreamWriter writer = factory.createXMLStreamWriter(this.socket.getOutputStream());
        XMLStreamWriter writer2 = factory.createXMLStreamWriter(System.out);

        System.out.println("waiting. write first value");
        input = scanner.nextLine();
        writer.writeStartDocument("1.0");
        writer.writeStartElement("root");
        writer.writeStartElement("key");
        writer.writeCharacters("FIRST");
        writer.writeEndElement();
        writer.writeStartElement("value");
        writer.writeCharacters(input);
        writer.writeEndElement();
        writer.writeEndElement();
        writer.writeEndDocument();

        //console check
        writer2.writeStartDocument("1.0");
        writer2.writeStartElement("root");
        writer2.writeStartElement("key");
        writer2.writeCharacters("FIRST");
        writer2.writeEndElement();
        writer2.writeStartElement("value");
        writer2.writeCharacters(input);
        writer2.writeEndElement();
        writer2.writeEndElement();
        writer2.writeEndDocument();


        //2 message
        System.out.println("\n\nwaiting. write second value\n");
        input = scanner.nextLine();

        writer.writeStartDocument("1.0");
        writer.writeStartElement("root");
        writer.writeStartElement("key");
        writer.writeCharacters("SECOND");
        writer.writeEndElement();
        writer.writeStartElement("value");
        writer.writeCharacters(input);
        writer.writeEndElement();
        writer.writeEndElement();
        writer.writeEndDocument();

        //вывод в консоль
        writer2.writeStartDocument("1.0");
        writer2.writeStartElement("root");
        writer2.writeStartElement("key");
        writer2.writeCharacters("SECOND");
        writer2.writeEndElement();
        writer2.writeStartElement("value");
        writer2.writeCharacters(input);
        writer2.writeEndElement();
        writer2.writeEndElement();
        writer2.writeEndDocument();

        System.out.println("\n\nPress somth to exit");

        writer2.flush();
        writer2.close();

        writer.flush();
        writer.close();

        input = scanner.nextLine();

    }
}

当我尝试发送第二个 XML时- 我收到错误

Exception in thread "main" javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,75]
Message: The processing instruction target matching "[xX][mM][lL]" is not allowed.

正如在stackoverflow post上所说的那样,这个错误的主要原因是错误的 XML 结构。我表示开始文档,结束文档......但它忽略了结束文档?我认为问题一定出在错误的发送方法上,但我找不到我必须更改的内容。

请帮忙

4

0 回答 0