2011-07-23 17 views
9

Tengo una arquitectura de servidor-cliente donde el cliente envía un XML al servidor que lo lee y genera un PDF y lo envía de vuelta al cliente.Desasignando InputStream de un socket cierra el socket?

En el lado del cliente:

JAXBElement<Xml> xml = ... 
Socket sock = ... 
Marshaller marshaller = ... 
marshaller.marshal(xml, sock.getOutputStream()); 
sock.shutdownOuput();  

Mientras tanto en el lado del servidor:

ServerSocket server = ... 
Socket client = server.accept(); 
Unmarshaller unmarshaller = ... 
// client.isClosed() -> false 
JAXBElement<Xml> xml = 
    (JAXBElement<Xml>)) unmarshaller.unmarshall(client.getInputStream()); 
// client.isClosed() -> true 
Pdf pdf = new Pdf(xml); 
client.getOutputStream().write(pdf.toBytes()); 
// "socket is closed" IOException is thrown 

Si no Resolver referencia de InputStream (en el lado del servidor) y acaba de enviar de vuelta un maniquí al cliente PDF, entonces todo va bien. Por lo tanto, tengo que asumir que el Unmarshaller cierra la InputStream se da, por lo tanto, implícitamente cerrar el cliente Socket arruinar mi día ...

Cualquier idea sobre la solución de este?

Respuesta

7

Las llamadas de la clase XMLEntityManager se cierran sobre el InputStream.

Puede usar un FilterInputStream para evitar una llamada close() de la transmisión subyacente.

Subclase FilterInputStream y anular el método close() con un cuerpo vacío:

public class MyInputStream extends FilterInputStream { 
    public MyInputStream(InputStream in) { 
    super(in); 
    } 

    @Override 
    public void close() { 
    // do nothing 
    } 
} 

luego cambia de Resolver referencia() para

JAXBElement<Xml> xml = 
    (JAXBElement<Xml>)) unmarshaller.unmarshall(new MyInputStream(client.getInputStream())); 

Así el marco JAXB todavía llama a close() en la secuencia, pero ahora está filtrada por su propia instancia de flujo y la secuencia de socket permanece abierta.

+0

Gracias, su la solución funciona como un encanto! :) –

6

Si no desea anular un InputStream explícitamente en su código como Vangé sugieren, Apache commons-io proporcionar una implementación que lograr esto:

echar un vistazo a:

CloseShieldInputStream

+0

Muy buena solución –

Cuestiones relacionadas