I have an API to which client can make request by sending the compressed request. Compression is done using the Deflator following way.
Request payload:
public byte[] compressRequest(String requestString) {
int reqLength = requestString.length();
int temp = (int)(1.001D * (double)reqLength + 1.0D) + 12;
byte[] byteArr = requestString.getBytes("US-ASCII");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(temp);
DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream);
deflaterOutputStream.write(byteArr);
deflaterOutputStream.close();
return byteArrayOutputStream.toByteArray();
}
At the server side, I am trying to extract and decompress the data following way.
The same code is working fine on Java7 and Servlet based application. But in java 8 and Spring boot based application I am getting following exception java.io.EOFException: Unexpected end of ZLIB input stream at line inputLine = in.readLine())
#PostMapping(value = "saverecord")
public void hello(HttpServletRequest request, HttpServletResponse response) {
response.setContentType("application/binary");
InflaterInputStream is = InflaterInputStream(request.getInputStream());
String requestXMLStr = extract(is, 0);
ServletOutputStream out = response
.getOutputStream();
// some processing and return response
}
private String extract(InputStream is) throws IOException {
StringBuffer sb = new StringBuffer();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = in.readLine()) != null) {
sb.append(inputLine);
}
return sb.toString();
}
I tried following two things suggested in other SO answers, but neither worked.
InflaterInputStream is = InflaterInputStream(request.getInputStream(), new Inflater(false)); // tried true also
tried setting up encoding
BufferedReader in = new BufferedReader(new InputStreamReader(is, "US-ASCII"));
PS: For some project specific reasons I cannot use #RequestBody in the project.
I'm pretty new to making HTTP connections and working with API's in Java, so I'm not sure where the problem lies. When I send out a POST connection request in order to send a JSON formatted String of text to the other side, I get an error back along with a 400 response code. When I look up that code, it seems my connection isn't properly formatted. Code is below, along with the error message. Please help! Thanks!
public void sendToAPI(String urlPass, String param) throws IOException {
URL url = new URL(urlPass);
HttpURLConnection connectionOut = (HttpURLConnection) url.openConnection();
connectionOut.setRequestMethod("POST");
connectionOut.setConnectTimeout(5000);
connectionOut.setReadTimeout(5000);
connectionOut.setRequestProperty("Content-Type", "application/json");
connectionOut.setRequestProperty("Content-Length", Integer.toString(param.length()));
connectionOut.setDoOutput(true);
connectionOut.setDoInput(true);
connectionOut.connect();
DataOutputStream stream = new DataOutputStream(connectionOut.getOutputStream());
stream.writeUTF(param);
stream.flush();
stream.close();
int responsecode = connectionOut.getResponseCode();
if(responsecode != 200) {
System.out.println("Response Code is " + responsecode);
}
BufferedReader in = new BufferedReader(
new InputStreamReader(connectionOut.getInputStream()));
String output;
StringBuffer response = new StringBuffer();
while ((output = in.readLine()) != null) {
response.append(output);
}
in.close();
//printing result from response
System.out.println(response.toString());
}
Response Code is 400
Exception in thread "main" java.io.IOException: Server returned HTTP response code: 400 for URL:XXX
u can try this code:
InputStream inputStream;
if (responseCode == 200) {
inputStream = con.getInputStream();
} else {
inputStream = con.getErrorStream();
}
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder builder = new StringBuilder();
String lines;
while ((lines = reader.readLine()) != null) {
builder.append(lines);
builder.append(System.getProperty("line.separator"));
}
String retStr = builder.toString().trim();
reader.close();
System.out.println("retStr: " + retStr);
So after playing around with the DataOutputStream, I replaced the below code:
DataOutputStream stream = new DataOutputStream(connectionOut.getOutputStream());
stream.writeUTF(param);
With another example I found online:
OutputStream os = connectionOut.getOutputStream();
os.write(param.getBytes());
os.flush();
os.close();
I'm not sure yet why, but this suddenly got the proper response code I was looking for, so the format it was sent in matched what they requested. Thanks for all responses.
In my android application am reading text file which is in server.
Am using below method.
private String getUrlContents(String UrlOfFile)
{
StringBuilder content = new StringBuilder();
try
{
URL url = new URL(UrlOfFile);
URLConnection urlConnection = url.openConnection();
BufferedReader bufferedReader = new BufferedReader(new
InputStreamReader(urlConnection.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null)
{
content.append(line + "\n");
}
bufferedReader.close();
}
catch(Exception e)
{
Log.d(TAG,"Exception >>>"+Log.getStackTraceString(e));
}
return content.toString();
}
But I am getting previous value of text file. When I once do clear data of app its able to get actual value.
Please help me to solve this issue.
My problem was due to returning of cached response.
Issue solved by urlConnection.setUseCaches(false);
Thanks to all responds,
How to prevent Android from returning a cached response to my HTTP Request?
Adding header for HttpURLConnection
I'm doing a simple JSON grab from two links with the same code. I'm doing it two separate times, so the cause of my issue isn't because they're running into each other or something.
Here is my code:
#Override
protected String doInBackground(Object... params) {
try {
URL weatherUrl = new URL("my url goes here");
HttpURLConnection connection = (HttpURLConnection) weatherUrl
.openConnection();
connection.connect();
responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();
Reader reader = new InputStreamReader(inputStream);
int contentLength = connection.getContentLength();
char[] charArray = new char[contentLength];
reader.read(charArray);
String responseData = new String(charArray);
Log.v("test", responseData);
When I try this with:
http://www.google.com/calendar/feeds/developer-calendar#google.com/public/full?alt=json
I get an error of having an array lenth of -1
For this link:
http://api.openweathermap.org/data/2.5/weather?id=5815135
It returns fine and I get a log of all of the JSON. Does anyone have any idea why?
Note: I tried stepping through my code in debug mode, but I couldn't catch anything. I also downloaded a Google chrome extension for parsing json in the browser and both urls look completely valid. I'm out of ideas.
Log this: int contentLength = connection.getContentLength();
I don't see the google url returning a content-length header.
If you just want String output from a url, you can use Scanner and URL like so:
Scanner s = new Scanner(new URL("http://www.google.com").openStream(), "UTF-8").useDelimiter("\\A");
out = s.next();
s.close();
(don't forget try/finally block and exception handling)
The longer way (which allows for progress reporting and such):
String convertStreamToString(InputStream is) throws UnsupportedEncodingException {
BufferedReader reader = new BufferedReader(new
InputStreamReader(is, "UTF-8"));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null)
sb.append(line + "\n");
} catch (IOException e) {
// Handle exception
} finally {
try {
is.close();
} catch (IOException e) {
// Handle exception
}
}
return sb.toString();
}
}
and then call String response = convertStreamToString( inputStream );
I have a javascript library that is sending a POST request to my Java servlet, but in the doPost method, I can't seem to get the contents of the request payload. In chrome Developer Tools, all the content is in the Request Payload section in the headers tab, and the content is there, and I know that the POST is being received by the doPost method, but it just comes up blank.
For the HttpServletRequest
object, what way can I get the data in the request payload?
Doing request.getParameter() or request.getAttributes()
both end up with no data
Simple answer:
Use getReader() to read the body of the request
More info:
There are two methods for reading the data in the body:
getReader() returns a BufferedReader that will allow you to read the body of the request.
getInputStream() returns a ServletInputStream if you need to read binary data.
Note from the docs: "[Either method] may be called to read the body, not both."
String payloadRequest = getBody(request);
Using this method
public static String getBody(HttpServletRequest request) throws IOException {
String body = null;
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
body = stringBuilder.toString();
return body;
}
You can use Buffer Reader from request to read
// Read from request
StringBuilder buffer = new StringBuilder();
BufferedReader reader = request.getReader();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
buffer.append(System.lineSeparator());
}
String data = buffer.toString()
Java 8 streams
String body = request.getReader().lines()
.reduce("", (accumulator, actual) -> accumulator + actual);
With Apache Commons IO you can do this in one line.
IOUtils.toString(request.getReader())
If the contents of the body are a string in Java 8 you can do:
String body = request.getReader().lines().collect(Collectors.joining());
If you are able to send the payload in JSON, this is a most convenient way to read the playload:
Example data class:
public class Person {
String firstName;
String lastName;
// Getters and setters ...
}
Example payload (request body):
{ "firstName" : "John", "lastName" : "Doe" }
Code to read payload in servlet (requires com.google.gson.*):
Person person = new Gson().fromJson(request.getReader(), Person.class);
That's all. Nice, easy and clean. Don't forget to set the content-type header to application/json.
Using Java 8 try with resources:
StringBuilder stringBuilder = new StringBuilder();
try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(request.getInputStream()))) {
char[] charBuffer = new char[1024];
int bytesRead;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
}
You only need
request.getParameterMap()
for getting the POST and GET - Parameters.
The Method returns a Map<String,String[]>.
You can read the parameters in the Map by
Map<String, String[]> map = request.getParameterMap();
//Reading the Map
//Works for GET && POST Method
for(String paramName:map.keySet()) {
String[] paramValues = map.get(paramName);
//Get Values of Param Name
for(String valueOfParam:paramValues) {
//Output the Values
System.out.println("Value of Param with Name "+paramName+": "+valueOfParam);
}
}