I have this InputStream:
InputStream inputStream = new ByteArrayInputStream(myString.getBytes(StandardCharsets.UTF_8));
How can I convert this to ServletInputStream?
I have tried:
ServletInputStream servletInputStream = (ServletInputStream) inputStream;
but do not work.
EDIT:
My method is this:
private static class LowerCaseRequest extends HttpServletRequestWrapper {
public LowerCaseRequest(final HttpServletRequest request) throws IOException, ServletException {
super(request);
}
@Override
public ServletInputStream getInputStream() throws IOException {
ServletInputStream servletInputStream;
StringBuilder jb = new StringBuilder();
String line;
String toLowerCase = "";
BufferedReader reader = new BufferedReader(new InputStreamReader(super.getInputStream()));
while ((line = reader.readLine()) != null) {
toLowerCase = jb.append(line).toString().toLowerCase();
}
InputStream inputStream = new ByteArrayInputStream(toLowerCase.getBytes(StandardCharsets.UTF_8));
servletInputStream = (ServletInputStream) inputStream;
return servletInputStream;
}
}
I´m trying to convert all my request to lowercase.
public abstract class ServletInputStream extends InputStream Provides an input stream for reading binary data from a client request, including an efficient readLine method for reading data one line at a time. With some protocols, such as HTTP POST and PUT, a ServletInputStream object can be used to read data sent from the client.
A ServletInputStream object is normally retrieved via the ServletRequest.getInputStream () method. This is an abstract class that a servlet container implements. Subclasses of this class must implement the java.io.InputStream.read () method. Author:
How to convert InputStream to File in Java. 1 1. Plain Java – FileOutputStream. This example downloads the google.com HTML page and returns it as an InputStream. And we use FileOutputStream to ... 2 2. Apache Commons IO. 3 3. Java 1.7 – Files.copy. 4 4. Java 9 – InputStream.transferTo. 5 5. Convert File to InputStream.
Two of the most important methods are read ( ) and write ( ), which are used for reading the client request and writing servlet response to client respectively. The ServletInputStream class extends java.io.InputStream.
My advice: don't create the ByteArrayInputStream
, just use the byte array you got from the getBytes
method already. This should be enough to create a ServletInputStream
.
Unfortunately, aksappy's answer only overrides the read
method. While this may be enough in Servlet API 3.0 and below, in the later versions of Servlet API there are three more methods you have to implement.
Here is my implementation of the class, although with it becoming quite long (due to the new methods introduced in Servlet API 3.1), you might want to think about factoring it out into a nested or even top-level class.
final byte[] myBytes = myString.getBytes("UTF-8");
ServletInputStream servletInputStream = new ServletInputStream() {
private int lastIndexRetrieved = -1;
private ReadListener readListener = null;
@Override
public boolean isFinished() {
return (lastIndexRetrieved == myBytes.length-1);
}
@Override
public boolean isReady() {
// This implementation will never block
// We also never need to call the readListener from this method, as this method will never return false
return isFinished();
}
@Override
public void setReadListener(ReadListener readListener) {
this.readListener = readListener;
if (!isFinished()) {
try {
readListener.onDataAvailable();
} catch (IOException e) {
readListener.onError(e);
}
} else {
try {
readListener.onAllDataRead();
} catch (IOException e) {
readListener.onError(e);
}
}
}
@Override
public int read() throws IOException {
int i;
if (!isFinished()) {
i = myBytes[lastIndexRetrieved+1];
lastIndexRetrieved++;
if (isFinished() && (readListener != null)) {
try {
readListener.onAllDataRead();
} catch (IOException ex) {
readListener.onError(ex);
throw ex;
}
}
return i;
} else {
return -1;
}
}
};
Depending on your requirements, you may also want to override other methods. As romfret pointed out, it's advisable to override some methods, such as close
and available
. If you don't implement them, the stream will always report that there are 0 bytes available to be read, and the close
method will do nothing to affect the state of the stream. You can probably get away without overriding skip
, as the default implementation will just call read
a number of times.
@Override
public int available() throws IOException {
return (myBytes.length-lastIndexRetrieved-1);
}
@Override
public void close() throws IOException {
lastIndexRetrieved = myBytes.length-1;
}
Unfortunately, due to the nature of an anonymous class, it's going to be difficult for you to write an effective close
method because as long as one instance of the stream has not been garbage-collected by Java, it maintains a reference to the byte array, even if the stream has been closed.
However, if you factor out the class into a nested or top-level class (or even an anonymous class with a constructor which you call from the line in which it is defined), the myBytes
can be a non-final field rather than a final local variable, and you can add a line like:
myBytes = null;
to your close
method, which will allow Java to free memory taken up by the byte array.
Of course, this will require you to write a constructor, such as:
private byte[] myBytes;
public StringServletInputStream(String str) {
try {
myBytes = str.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("JVM did not support UTF-8", e);
}
}
You may also want to override mark
, markSupported
and reset
if you want to support mark/reset. I am not sure if they are ever actually called by your container though.
private int readLimit = -1;
private int markedPosition = -1;
@Override
public boolean markSupported() {
return true;
}
@Override
public synchronized void mark(int readLimit) {
this.readLimit = readLimit;
this.markedPosition = lastIndexRetrieved;
}
@Override
public synchronized void reset() throws IOException {
if (markedPosition == -1) {
throw new IOException("No mark found");
} else {
lastIndexRetrieved = markedPosition;
readLimit = -1;
}
}
// Replacement of earlier read method to cope with readLimit
@Override
public int read() throws IOException {
int i;
if (!isFinished()) {
i = myBytes[lastIndexRetrieved+1];
lastIndexRetrieved++;
if (isFinished() && (readListener != null)) {
try {
readListener.onAllDataRead();
} catch (IOException ex) {
readListener.onError(ex);
throw ex;
}
readLimit = -1;
}
if (readLimit != -1) {
if ((lastIndexRetrieved - markedPosition) > readLimit) {
// This part is actually not necessary in our implementation
// as we are not storing any data. However we need to respect
// the contract.
markedPosition = -1;
readLimit = -1;
}
}
return i;
} else {
return -1;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With