我正在学习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 结构。我表示开始文档,结束文档......但它忽略了结束文档?我认为问题一定出在错误的发送方法上,但我找不到我必须更改的内容。
请帮忙