Penso di aver capito qual è il problema. Quando gli dici:
codice:
BufferedImage bu = new BufferedImage(image.getWidth(null),image.getHeight(null),BufferedImage.TYPE_INT_RGB);
stai creando una NUOVA immagine "nera", avente le stesse dimensioni dell'immagine che hai caricato. Poi tu vai a scrivere sullo stream di output questa nuova immagine, NON quella che invece vorresti inviare!
Non ho provato, ma ti dovrebbe essere sufficiente eliminare tutti i riferimenti alla variabile "bu" ed usare invece solo la "image" (che puoi dichiarare come BufferedImage).
Io ho fatto una semplice prova con il codice:
codice:
BufferedImage image = ImageIO.read(url);
response.setContentType("image/jpg");
ImageIO.write(image, "jpg", response.getOutputStream());
invece del tuo, ma ho notato che l'immagine che viene ritornata e salva il client ha una dimensione in byte diversa da quella originale. Fai delle prove, ma comunque per il resto la logica del tuo algoritmo mi sembra corretta