I am developing a custom log with Spring MVC to get information from all incoming request. I would like to grab both the request body and response body. The issue is, even if I create a HttpServletRequestWrapper, I cannot forward the request after I process and wrap the request.
Here is my code:
Interceptor
#Component
public class LoggerInterceptor implements HandlerInterceptor{
final static org.apache.log4j.Logger log = Logger.getLogger(LoggerInterceptor.class.getName());
/**
* Executed before actual handler is executed
**/
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
long start = System.currentTimeMillis();
MyRequestWrapper requestWrapper = new MyRequestWrapper(request);
SimpleDateFormat f = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
String date = f.format(new Date());
UUID uuid = UUID.randomUUID();
String method = requestWrapper.getMethod();
String uri = requestWrapper.getRequestURI();
String step = "Default Step";
String url = String.valueOf(requestWrapper.getRequestURL());
String serverName = requestWrapper.getServerName();
String reqBody = IOUtils.toString(requestWrapper.getInputStream(), Charset.forName("UTF-8").toString());
CustomHttpResponseWrapper responseWrapper = new CustomHttpResponseWrapper(response);
long end = System.currentTimeMillis() - start;
String status = String.valueOf(responseWrapper.getStatus());
String resBody = new String(responseWrapper.getBaos().toByteArray());
if(step!=null && !step.isEmpty()) {
log.info("INFO " + date + " " + uuid + "\n" +
"ID : " + getCurrentlyDateTime() + "\n" +
"STEP : " + step + "\n" +
"Request URL: " + url + "\n" +
"Host : " + serverName + "\n" +
"Request Body : " + reqBody + "\n" +
"Response Status : " + status + "\n" +
"Response Body : " + resBody + "\n" +
"Response Time : " + end);
}
return true;
}
}
Request Wrapper
public class MyRequestWrapper extends HttpServletRequestWrapper {
private final String body;
public MyRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
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();
}
#Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
public int read() throws IOException {
return byteArrayInputStream.read();
}
#Override
public boolean isFinished() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isReady() {
// TODO Auto-generated method stub
return false;
}
#Override
public void setReadListener(ReadListener readListener) {
// TODO Auto-generated method stub
}
};
return servletInputStream;
}
#Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBody() {
return this.body;
}
}
Output
INFO 2022/04/12 10:35:18:578 d00ec778-2a6e-4a72-a0e0-9649c13776eb
ID : 20220412103518
STEP : Default Step
Request URL: http://localhost:8080/com.ihcs.api.mobile/loginNew
Host : localhost
Request Body : {
"username":"P0****",
"sessionid":"*************************",
"password":"********",
"companyCode":"***",
"UniqueId":"**********",
"Manufacturer":"google",
"Brand":"google",
"Model":"*******",
"DeviceId":"*******",
"FcmTokens":"*******",
"UniqueLogin":false
}
Response Status : 200
Response Body :
Response Time : 18
Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: I/O error while reading input message; nested exception is java.io.IOException: Stream closed
I've tried some suggestions from stack overflow but still can't help. Thank you.
Related
When I call the web service it responds with 403 and some data in response like these.
{
"code": "[jwt_auth] invalid_email",
"message": "Dummy MEssage",
"data": {
"status": 403
}
}
My code is as given below
final AsyncTask<Void, String, String> waitForCompletion = new AsyncTask<Void, String, String>() {
ProgressDialog progressDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
//Show Progress
}
#Override
public synchronized String doInBackground(Void... params) {
String res = "";
String charset = "UTF-8";
String requestURL = "www.myurl.com";
try {
MultipartUtility multipart = new MultipartUtility(requestURL, charset);
multipart.addFormField("username", email);
multipart.addFormField("password", password);
List<String> response = multipart.finish();
for (String line : response) {
System.out.println(line);
res = line;
Log.d("Message" , "Obtained" + response);
}
} catch (IOException ex) {
System.err.println(ex);
dismissProgressDialog(progressDialog);
}
return res;
}
#Override
protected void onPostExecute(String result) {
dismissProgressDialog(progressDialog);
if (hasValue(result)) {
UserLogin response = (new Gson()).fromJson(result, new TypeToken<UserLogin>() {
}.getType());
if (result.contains("message")) {
// Show error message
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
showMessageAlert(Html.fromHtml(response.getMessage(), Html.FROM_HTML_MODE_COMPACT), getString(R.string.app_name), LoginActivity.this);
} else {
showMessageAlert(Html.fromHtml(response.getMessage()), getString(R.string.app_name), LoginActivity.this);
}
} else {
setUserId(LoginActivity.this , String.valueOf(response.getUserId()));
setToken(LoginActivity.this, response.getToken());
setLoginInformation(LoginActivity.this, result);
Intent intent = new Intent(LoginActivity.this, PickSportsActivity.class);
startActivity(intent);
finish();
}
}
}
};
The Issue is how can I get the response when I am getting errors of 403 and 404 in response. How can I fetch the response that I am getting even when I get these errors.
Here is my Multipart Code
public class MultipartUtility {
private final String boundary;
private static final String LINE_FEED = "\r\n";
private HttpURLConnection httpConn;
private String charset;
private OutputStream outputStream;
private PrintWriter writer;
StringBuilder result;
/**
* This constructor initializes a new HTTP POST request with content type
* is set to multipart/form-data
* #param requestURL
* #param charset
* #throws IOException
*/
public MultipartUtility(String requestURL, String charset)
throws IOException {
this.charset = charset;
// creates a unique boundary based on time stamp
boundary = "===" + System.currentTimeMillis() + "===";
URL url = new URL(requestURL);
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setUseCaches(false);
httpConn.setDoOutput(true); // indicates POST method
httpConn.setDoInput(true);
httpConn.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + boundary);
httpConn.addRequestProperty("TOKEN", "Zml0c29vOmZpdHNvb0Aj");
// httpConn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
// httpConn.addRequestProperty("content-type", "application/x-www-form-urlencoded");httpConn.setRequestProperty("content-type", "application/x-www-form-urlencoded; charset=utf-8");
/* httpConn.setRequestProperty("User-Agent", "CodeJava Agent");
httpConn.setRequestProperty("Test", "Bonjour");*/
outputStream = httpConn.getOutputStream();
writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
true);
}
/**
* Adds a form field to the request
* #param name field name
* #param value field value
*/
public void addFormField(String name, String value) {
writer.append("--" + boundary).append(LINE_FEED);
writer.append("Content-Disposition: form-data; name=\"" + name + "\"")
.append(LINE_FEED);
writer.append("Content-Type: text/plain; charset=" + charset).append(
LINE_FEED);
writer.append(LINE_FEED);
writer.append(value).append(LINE_FEED);
writer.flush();
result = new StringBuilder();
boolean first = true;
if (first)
first = false;
else
result.append("&");
try {
result.append(URLEncoder.encode(name, "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(value, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
* Adds a upload file section to the request
* #param fieldName name attribute in <input type="file" name="..." />
* #param uploadFile a File to be uploaded
* #throws IOException
*/
public void addFilePart(String fieldName, File uploadFile)
throws IOException {
String fileName = uploadFile.getName();
writer.append("--" + boundary).append(LINE_FEED);
writer.append(
"Content-Disposition: form-data; name=\"" + fieldName
+ "\"; filename=\"" + fileName + "\"")
.append(LINE_FEED);
writer.append(
"Content-Type: "
+ URLConnection.guessContentTypeFromName(fileName))
.append(LINE_FEED);
writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
writer.append(LINE_FEED);
writer.flush();
FileInputStream inputStream = new FileInputStream(uploadFile);
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
inputStream.close();
writer.append(LINE_FEED);
writer.flush();
try {
result.append(URLEncoder.encode(fieldName, "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(fileName, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
* Adds a header field to the request.
* #param name - name of the header field
* #param value - value of the header field
*/
public void addHeaderField(String name, String value) {
writer.append(name + ": " + value).append(LINE_FEED);
writer.flush();
}
/**
* Completes the request and receives response from the server.
* #return a list of Strings as response in case the server returned
* status OK, otherwise an exception is thrown.
* #throws IOException
*/
public List<String> finish() throws IOException {
List<String> response = new ArrayList<String>();
writer.append(LINE_FEED).flush();
writer.append("--" + boundary + "--").append(LINE_FEED);
writer.close();
// checks server's status code first
int status = httpConn.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpConn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
response.add(line);
}
reader.close();
httpConn.disconnect();
}
else if(status==500){
throw new IOException("Server HTTP_INTERNAL_ERROR : " + status);
}else {
throw new IOException("Server returned non-OK status: " + status);
}
return response;
}
}
In your finish method code see the int variable status.
This status variable will provide you the response code returned from the server.
The if condition in the code checks for response code 200 & 500. You can add your own logic for the same.
Also you can simplify your finish method code by using StringBuilder instead of using arraylist as response.
I can send notifications to my Android application using another 3rd party server, I can also send notifications from the firebase console, however this servlet (code below) is not sending a notification although the HTTP POST to FCM results in a successful 200 return message.
I think the servlet does not contain code that creates a notification and I am not sure where to exactly create this code. I would like some input.
#WebServlet("/NPS_Servlet")
public class NPS_Servlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static HashMap<String, Confirmation> TFA = new HashMap<String, Confirmation>();
/**
* #see HttpServlet#HttpServlet()
*/
public NPS_Servlet() {
super();
System.out.println("Servlet gestart");
// TODO Auto-generated constructor stub
}
/**
* #see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
NPS_Servlet Servlet = new NPS_Servlet();
Servlet.processAuthenticate(null, null);
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
processRequest(request, response);
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
private void processRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
InputStreamReader isr_Json_Request = null;
isr_Json_Request = new InputStreamReader(request.getInputStream());
ByteArrayOutputStream baos_Json_Request = new ByteArrayOutputStream();
int byteRead = 0;
do {
byteRead = 0;
byteRead = isr_Json_Request.read();
if (byteRead >= 0) {
baos_Json_Request.write(byteRead);
}
} while (byteRead >= 0);
String s_Json_Request = baos_Json_Request.toString();
String s_RequestURI = request.getRequestURI();
String s_ContextPath = request.getContextPath();
String s_Request_Prefix = s_ContextPath;
String s_Request = s_RequestURI.substring(s_Request_Prefix.length(), s_RequestURI.length());
if (! s_Request.startsWith("/")) {
s_Request = "/" + s_Request;
}
System.out.println("Request: " + s_Request);
String s_Response = "";
if (s_Request.equals("/TFA_Servlet_Rami_FinalTake/authenticate")) {
s_Response = handleAuthenticate(s_Json_Request);
}
else if (s_Request.equals("/TFA_Servlet_Rami_FinalTake/confirm")) {
s_Response = handleConfirm(s_Json_Request);
}
System.out.println("Response: " + s_Response);
response.getWriter().print(s_Response);
}
private String handleAuthenticate(String s_Json_Request) {
String s_Json_Response = "";
Gson _Gson = new Gson();
Message json_Request = _Gson.fromJson(s_Json_Request,
Message.class);
if (json_Request != null) {
if (json_Request.getFunction().equals("authenticate")) {
Message json_Response;
try {
json_Response = (Message) json_Request.clone();
processAuthenticate(json_Request, json_Response);
s_Json_Response = _Gson.toJson(json_Response);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
if (s_Json_Response.isEmpty()) {
s_Json_Response = "{ \"result\":1 }";
}
return s_Json_Response;
}
private void processAuthenticate(Message json_Request, Message json_Response){
String s_RegistrationId = "AAAA-NCJai&*******9n&&&****f3gRYjH7*******Nh***********PsedxBhKsrFCuF";
String s_ApiKey = "AIz************EM";
String uniqueID = UUID.randomUUID().toString();;
String s_Data = "";
try {
s_Data = "{" +
"\"data\": {" +
"\"url\": \"http://" + InetAddress.getLocalHost().getHostAddress() + ":8080/TFA_Servlet/confirm\"," +
"\"id\": \"" + uniqueID + "\"" +
"}," +
"\"to\": \"" + s_RegistrationId + "\"" +
"}";
} catch (UnknownHostException e1) {
e1.printStackTrace();
}
try {
URL _URL = new URL("https://fcm.googleapis.com/fcm/send");
HttpURLConnection _HttpURLConnection = (HttpURLConnection) _URL.openConnection();
_HttpURLConnection.setRequestMethod("POST");
_HttpURLConnection.setRequestProperty("Content-Type", "application/json");
_HttpURLConnection.setRequestProperty("Authorization", "key=" + s_RegistrationId);
_HttpURLConnection.setDoOutput(true);
DataOutputStream _DataOutputStream = new DataOutputStream(_HttpURLConnection.getOutputStream());
_DataOutputStream.writeBytes(s_Data);
_DataOutputStream.flush();
_DataOutputStream.close();
int responseCode = _HttpURLConnection.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + _URL);
System.out.println("Response Code : " + responseCode);
BufferedReader _BufferedReader = new BufferedReader(
new InputStreamReader(_HttpURLConnection.getInputStream()));
String inputLine;
StringBuffer Response = new StringBuffer();
while ((inputLine = _BufferedReader.readLine()) != null) {
Response.append(inputLine);
}
_BufferedReader.close();
if (responseCode == 200) {
System.out.println("succes");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private String handleConfirm(String s_Json_Request) {
String s_Json_Response = "";
Gson _Gson = new Gson();
Message json_Request = _Gson.fromJson(s_Json_Request,
Message.class);
if (json_Request != null) {
if (json_Request.getFunction().equals("confirm")) {
Message json_Response;
try {
json_Response = (Message) json_Request.clone();
processConfirm(json_Request, json_Response);
s_Json_Response = _Gson.toJson(json_Response);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
if (s_Json_Response.isEmpty()) {
s_Json_Response = "{ \"result\":1 }";
}
return s_Json_Response;
}
private void processConfirm(Message json_Request, Message json_Response) {
String s_NotificationId = json_Request.getNotificationId();
String s_Confirmation = json_Request.getConfirmation();
Confirmation _Confirmation = null;
synchronized (TFA) {
_Confirmation = TFA.get(s_NotificationId);
if (TFA != null) {
_Confirmation.setReplied(true);
if (s_Confirmation.equals("approved")) {
_Confirmation.setConfirmed(true);
}
json_Response.setResult(0);
TFA.notifyAll();
}
else {
json_Response.setResult(1);
}
}
}
}
REQUEST PART (included above as well but separated for visibility purpose)
private void processAuthenticate(Message json_Request, Message json_Response){
String s_RegistrationId = "AAAA-NCJais:APA91bH2i5FGIhBhMj3YEf0yCqYMKh0FQna9tUTVQDnhw63vM3KyjgMMhXPG6NLA9nrFagr81bSFjezf3gRYjH7OoCp3AWnd9a3cPv6DNhAORIltEwYFooFKYlKyAGPsedxBhKsrFCuF";
String s_ApiKey = "AIzaSyAFFBOrTyvT-vipBEOZTtMlEsdeveVx8EM";
String uniqueID = UUID.randomUUID().toString();;
String s_Data = "";
try {
s_Data = "{" +
"\"data\": {" +
"\"url\": \"http://" + InetAddress.getLocalHost().getHostAddress() + ":8080/TFA_Servlet/confirm\"," +
"\"id\": \"" + uniqueID + "\"" +
"}," +
"\"to\": \"" + s_RegistrationId + "\"" +
"}";
} catch (UnknownHostException e1) {
e1.printStackTrace();
}
try {
URL _URL = new URL("https://fcm.googleapis.com/fcm/send");
HttpURLConnection _HttpURLConnection = (HttpURLConnection) _URL.openConnection();
_HttpURLConnection.setRequestMethod("POST");
_HttpURLConnection.setRequestProperty("Content-Type", "application/json");
_HttpURLConnection.setRequestProperty("Authorization", "key=" + s_RegistrationId);
_HttpURLConnection.setDoOutput(true);
DataOutputStream _DataOutputStream = new DataOutputStream(_HttpURLConnection.getOutputStream());
_DataOutputStream.writeBytes(s_Data);
_DataOutputStream.flush();
_DataOutputStream.close();
int responseCode = _HttpURLConnection.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + _URL);
System.out.println("Response Code : " + responseCode);
BufferedReader _BufferedReader = new BufferedReader(
new InputStreamReader(_HttpURLConnection.getInputStream()));
String inputLine;
StringBuffer Response = new StringBuffer();
while ((inputLine = _BufferedReader.readLine()) != null) {
Response.append(inputLine);
}
_BufferedReader.close();
if (responseCode == 200) {
System.out.println("succes");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
*************************** RESPONSE PART ********************************
Sending 'POST' request to URL : https://fcm.googleapis.com/fcm/send
Response Code : 200
succes
So currently, I'm trying to import some data in the form of an XML file to a server. I have successfully logged in and am doing everything through the API of the server. The website/server responds in XML, not sure if that is relevant.
When I use the import data action of the API, the request method is actually a GET and not a POST and the response content-type is text/xml. I want to strictly stick to using HttpURLConnection and I understand that sending this XML file will require some multipart content-type thing but I'm not really sure how to proceed from here.
I've looked at these two examples but it does not work for my application (at least not directly). In addition, I don't really understand where they got some of the request headers from.
Send .txt file, document file to the server in android
http://alt236.blogspot.ca/2012/03/java-multipart-upload-code-android.html
A message from one of the developers have said "To upload the data use the action=importData&gwID=nnnn and with the usual
Multipart content encoding and place the files in the request body as usual."
How would I send my XML file to my server through its API?
This is how you do it:
public void postToUrl(String payload, String address, String subAddress) throws Exception
{
try
{
URL url = new URL(address);
URLConnection uc = url.openConnection();
HttpURLConnection conn = (HttpURLConnection) uc;
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-type", "text/xml");
PrintWriter pw = new PrintWriter(conn.getOutputStream());
pw.write(payload);
pw.close();
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
bis.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
This is my implementation of a Multipart form data upload using HttpURLConnection.
public class WebConnector {
String boundary = "-------------" + System.currentTimeMillis();
private static final String LINE_FEED = "\r\n";
private static final String TWO_HYPHENS = "--";
private StringBuilder url;
private String protocol;
private HashMap<String, String> params;
private JSONObject postData;
private List<String> fileList;
private int count = 0;
private DataOutputStream dos;
public WebConnector(StringBuilder url, String protocol,
HashMap<String, String> params, JSONObject postData) {
super();
this.url = url;
this.protocol = protocol;
this.params = params;
this.postData = postData;
createServiceUrl();
}
public WebConnector(StringBuilder url, String protocol,
HashMap<String, String> params, JSONObject postData, List<String> fileList) {
super();
this.url = url;
this.protocol = protocol;
this.params = params;
this.postData = postData;
this.fileList = fileList;
createServiceUrl();
}
public String connectToMULTIPART_POST_service(String postName) {
System.out.println(">>>>>>>>>url : " + url);
StringBuilder stringBuilder = new StringBuilder();
String strResponse = "";
InputStream inputStream = null;
HttpURLConnection urlConnection = null;
try {
urlConnection = (HttpURLConnection) new URL(url.toString()).openConnection();
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setRequestProperty("Connection", "close");
urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 ( compatible ) ");
urlConnection.setRequestProperty("Authorization", "Bearer " + Config.getConfigInstance().getAccessToken());
urlConnection.setRequestProperty("Content-type", "multipart/form-data; boundary=" + boundary);
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.setUseCaches(false);
urlConnection.setChunkedStreamingMode(1024);
urlConnection.setRequestMethod("POST");
dos = new DataOutputStream(urlConnection.getOutputStream());
Iterator<String> keys = postData.keys();
while (keys.hasNext()) {
try {
String id = String.valueOf(keys.next());
addFormField(id, "" + postData.get(id));
System.out.println(id + " : " + postData.get(id));
} catch (JSONException e) {
e.printStackTrace();
}
}
try {
dos.writeBytes(LINE_FEED);
dos.flush();
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
if (fileList != null && fileList.size() > 0 && !fileList.isEmpty()) {
for (int i = 0; i < fileList.size(); i++) {
File file = new File(fileList.get(i));
if (file != null) ;
addFilePart("photos[" + i + "][image]", file);
}
}
// forming th java.net.URL object
build();
urlConnection.connect();
int statusCode = 0;
try {
urlConnection.connect();
statusCode = urlConnection.getResponseCode();
} catch (EOFException e1) {
if (count < 5) {
urlConnection.disconnect();
count++;
String temp = connectToMULTIPART_POST_service(postName);
if (temp != null && !temp.equals("")) {
return temp;
}
}
} catch (IOException e) {
e.printStackTrace();
}
// 200 represents HTTP OK
if (statusCode == HttpURLConnection.HTTP_OK) {
inputStream = new BufferedInputStream(urlConnection.getInputStream());
strResponse = readStream(inputStream);
} else {
System.out.println(urlConnection.getResponseMessage());
inputStream = new BufferedInputStream(urlConnection.getInputStream());
strResponse = readStream(inputStream);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != inputStream)
inputStream.close();
} catch (IOException e) {
}
}
return strResponse;
}
public void addFormField(String fieldName, String value) {
try {
dos.writeBytes(TWO_HYPHENS + boundary + LINE_FEED);
dos.writeBytes("Content-Disposition: form-data; name=\"" + fieldName + "\"" + LINE_FEED + LINE_FEED/*+ value + LINE_FEED*/);
/*dos.writeBytes("Content-Type: text/plain; charset=UTF-8" + LINE_FEED);*/
dos.writeBytes(value + LINE_FEED);
} catch (IOException e) {
e.printStackTrace();
}
}
public void addFilePart(String fieldName, File uploadFile) {
try {
dos.writeBytes(TWO_HYPHENS + boundary + LINE_FEED);
dos.writeBytes("Content-Disposition: form-data; name=\"" + fieldName + "\";filename=\"" + uploadFile.getName() + "\"" + LINE_FEED);
dos.writeBytes(LINE_FEED);
FileInputStream fStream = new FileInputStream(uploadFile);
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int length = -1;
while ((length = fStream.read(buffer)) != -1) {
dos.write(buffer, 0, length);
}
dos.writeBytes(LINE_FEED);
dos.writeBytes(TWO_HYPHENS + boundary + TWO_HYPHENS + LINE_FEED);
/* close streams */
fStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void addHeaderField(String name, String value) {
try {
dos.writeBytes(name + ": " + value + LINE_FEED);
} catch (IOException e) {
e.printStackTrace();
}
}
public void build() {
try {
dos.writeBytes(LINE_FEED);
dos.flush();
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static String readStream(InputStream in) {
StringBuilder sb = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String nextLine = "";
while ((nextLine = reader.readLine()) != null) {
sb.append(nextLine);
}
/* Close Stream */
if (null != in) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
private void createServiceUrl() {
if (null == params) {
return;
}
final Iterator<Map.Entry<String, String>> it = params.entrySet().iterator();
boolean isParam = false;
while (it.hasNext()) {
final Map.Entry<String, String> mapEnt = (Map.Entry<String, String>) it.next();
url.append(mapEnt.getKey());
url.append("=");
try {
url.append(URLEncoder.encode(mapEnt.getValue(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
url.append(WSConstants.AMPERSAND);
isParam = true;
}
if (isParam) {
url.deleteCharAt(url.length() - 1);
}
}
}
I am trying to build a simple HTTP client program that sends a request to a web server and prints the response out to the user.
I have got the following error when I run my code and I am not sure what is causing it:
-1
Exception in thread "main" java.lang.IllegalArgumentException: port out of range:-1
at java.net.InetSocketAddress.(InetSocketAddress.java:118)
at java.net.Socket.(Socket.java:189)
at com.example.bookstore.MyHttpClient.execute(MyHttpClient.java:18)
at com.example.bookstore.MyHttpClientApp.main(MyHttpClientApp.java:29)
Java Result: 1
Below is my MyHttpClient.java class
public class MyHttpClient {
MyHttpRequest request;
public MyHttpResponse execute(MyHttpRequest request) throws IOException {
this.request = request;
int port = request.getPort();
System.out.println(port);
//Create a socket
Socket s = new Socket(request.getHost(), request.getPort());
//Create I/O streams
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter outToServer = new PrintWriter(s.getOutputStream());
//Get method (POST OR GET) from request
String method = request.getMethod();
//Create response
MyHttpResponse response = new MyHttpResponse();
//GET Request
if(method.equalsIgnoreCase("GET")){
//Construct request line
String path = request.getPath();
String queryString = request.getQueryString();
//Send request line to server
outToServer.println("GET " + path + " HTTP/1.0");
//=================================================\\
//HTTP RESPONSE
//RESPONSE LINE
//Read response from server
String line = inFromServer.readLine();
//Get response code - should be 200.
int status = Integer.parseInt(line.substring(9, 3));
//Get text description of response code - if 200 should be OK.
String desc = line.substring(13);
//HEADER LINES
//Loop through headers until get to blank line...
//Header name: Header Value - structure
do{
line = inFromServer.readLine();
if(line != null && line.length() == 0){
//line is not blank
//header name start of line to the colon.
String name = line.substring(0, line.indexOf(": "));
//header value after the colon to end of line.
String value = String.valueOf(line.indexOf(": "));
response.addHeader(name, value);
}
}while(line != null && line.length() == 0);
//MESSAGE BODY
StringBuilder sb = new StringBuilder();
do{
line = inFromServer.readLine();
if(line != null){
sb.append((line)+"\n");
}
}while(line != null);
String body = sb.toString();
response.setBody(body);
//return response
return response;
}
//POST Request
else if(method.equalsIgnoreCase("POST")){
return response;
}
return response;
}
}
This is the MyHttpClientApp.java class
public class MyHttpClientApp {
public static void main(String[] args) {
String urlString = null;
URI uri;
MyHttpClient client;
MyHttpRequest request;
MyHttpResponse response;
try {
//==================================================================
// send GET request and print response
//==================================================================
urlString = "http://127.0.0.1/bookstore/viewBooks.php";
uri = new URI(urlString);
client = new MyHttpClient();
request = new MyHttpRequest(uri);
request.setMethod("GET");
response = client.execute(request);
System.out.println("=============================================");
System.out.println(request);
System.out.println("=============================================");
System.out.println(response);
System.out.println("=============================================");
}
catch (URISyntaxException e) {
String errorMessage = "Error parsing uri (" + urlString + "): " + e.getMessage();
System.out.println("MyHttpClientApp: " + errorMessage);
}
catch (IOException e) {
String errorMessage = "Error downloading book list: " + e.getMessage();
System.out.println("MyHttpClientApp: " + errorMessage);
}
}
}
MyHttpRequest
public class MyHttpRequest {
private URI uri;
private String method;
private Map<String, String> params;
public MyHttpRequest(URI uri) {
this.uri = uri;
this.method = null;
this.params = new HashMap<String, String>();
}
public String getHost() {
return this.uri.getHost();
}
public int getPort() {
return this.uri.getPort();
}
public String getPath() {
return this.uri.getPath();
}
public void addParameter(String name, String value) {
try {
name = URLEncoder.encode(name, "UTF-8");
value = URLEncoder.encode(value, "UTF-8");
this.params.put(name, value);
}
catch (UnsupportedEncodingException ex) {
System.out.println("URL encoding error: " + ex.getMessage());
}
}
public Map<String, String> getParameters() {
return this.params;
}
public String getQueryString() {
Map<String, String> parameters = this.getParameters();
// construct StringBuffer with name/value pairs
Set<String> names = parameters.keySet();
StringBuilder sbuf = new StringBuilder();
int i = 0;
for (String name : names) {
String value = parameters.get(name);
if (i != 0) {
sbuf.append("&");
}
sbuf.append(name);
sbuf.append("=");
sbuf.append(value);
i++;
}
return sbuf.toString();
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
#Override
public String toString() {
StringBuilder sbuf = new StringBuilder();
sbuf.append(this.getMethod());
sbuf.append(" ");
sbuf.append(this.getPath());
if (this.getMethod().equals("GET")) {
if (this.getQueryString().length() > 0) {
sbuf.append("?");
sbuf.append(this.getQueryString());
}
sbuf.append("\n");
sbuf.append("\n");
}
else if (this.getMethod().equals("POST")) {
sbuf.append("\n");
sbuf.append("\n");
sbuf.append(this.getQueryString());
sbuf.append("\n");
}
return sbuf.toString();
}
}
MyHttpResponse
public class MyHttpResponse {
private int status;
private String description;
private Map<String, String> headers;
private String body;
public MyHttpResponse() {
this.headers = new HashMap<String, String>();
}
public int getStatus() {
return this.status;
}
public void setStatus(int status) {
this.status = status;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public Map<String, String> getHeaders() {
return this.headers;
}
public void addHeader(String header, String value) {
headers.put(header, value);
}
public String getBody() {
return body;
}
public void setBody(String is) {
this.body = is;
}
#Override
public String toString() {
StringBuilder sbuf = new StringBuilder();
sbuf.append("Http Response status line: ");
sbuf.append("\n");
sbuf.append(this.getStatus());
sbuf.append(" ");
sbuf.append(this.getDescription());
sbuf.append("\n");
sbuf.append("---------------------------------------------");
sbuf.append("\n");
sbuf.append("Http Response headers: ");
sbuf.append("\n");
for (String key: this.getHeaders().keySet()) {
String value = this.getHeaders().get(key);
sbuf.append(key);
sbuf.append(": ");
sbuf.append(value);
sbuf.append("\n");
}
sbuf.append("---------------------------------------------");
sbuf.append("\n");
sbuf.append("Http Response body: ");
sbuf.append("\n");
sbuf.append(this.getBody());
sbuf.append("\n");
return sbuf.toString();
}
}
Any ideas what might be happening? Many thanks in advance.
I guess your request don't specify a port explicitly and so your request.getPort() is returning -1. And then you try to connect to port -1. And this is illegal.
Instead of that, before using the port : check if it is <= 0 and in this case use 80 as default value.
int port = request.getPort();
if(port<=0) port=80;
since there is no set port in the URI, as of javadocs -1 is returned from port:
http://docs.oracle.com/javase/6/docs/api/java/net/URI.html#getPort()
The port component of this URI, or -1 if the port is undefined
Lots of recreating the wheel going on here. Why not use Java's in-built HTTP client (at least; there are also many third-party HTTP clients out there that do very nicely).
URL url = new URL("http://stackoverflow.com");
final HttpURLConnection connection = url.openConnection();
connection.setDoInput(true);
connection.connect();
int responseCode = connection.getResponseCode();
etc.
use
uri = URIUtil.encodeQuery(urlString)
instead
uri = new URI(urlString);
I have been playing around with Java httpServer class a little bit. When I run my test application it will get to the last line (a println) in main about right a way, but then it sits there for about 45 secs before closing the application. Why does it do that and is there a way to make it so it ends faster? Thanks
public class TestTester
{
public static void main(String[] args) throws IOException {
InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 8780);
HttpServer server = HttpServer.create(addr, 0);
server.createContext("/", new MyHandler());
server.setExecutor(Executors.newCachedThreadPool());
server.start();
URL url = new URL("http://localhost:8780/test");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
InputStreamReader(connection.getInputStream()));
// print out the response headers
System.out.println("\nHttp Response Headers");
for (int i=0; ; i++)
{
String headerName = connection.getHeaderFieldKey(i);
String headerValue = connection.getHeaderField(i);
if (headerName == null && headerValue == null) {
// No more headers
break;
}
else if (headerName == null) {
System.out.println( " " + headerValue);
}
else
System.out.println( " " + headerName + ": " + headerValue );
}
connection.disconnect();
server.stop(0);
System.out.println("Stopped Server.");
} // end main()
}
class MyHandler implements HttpHandler {
#Override
public void handle(HttpExchange exchange) throws IOException
{
System.out.println("===Enter MyHandler===");
System.out.println("Http Request Header:");
// print out the request methode and url
System.out.println( " " + exchange.getRequestMethod() + " "
+ exchange.getRequestURI() + " " + exchange.getProtocol());
// print out the request headers
Headers requestHeaders = exchange.getRequestHeaders();
for (String name : requestHeaders.keySet() )
{
List<String> values = requestHeaders.get(name);
for ( String value : values )
{
System.out.println( " " + name + ": " + value);
}
}
// print out the request body if any
BufferedReader in = new BufferedReader(new InputStreamReader(exchange.getRequestBody()));
String sCurrentLine;
System.out.println( "\nHttp Request Body:");
if ( ! in.ready() )
System.out.println( " No Request Body");
else
{
while ((sCurrentLine = in.readLine()) != null) {
System.out.println(" " + sCurrentLine);
}
}
// set up and send response
String requestMethod = exchange.getRequestMethod();
if (requestMethod.equalsIgnoreCase("GET"))
{
Headers responseHeaders = exchange.getResponseHeaders();
responseHeaders.set("Content-Type", "text/html");
exchange.sendResponseHeaders(200, 0);
OutputStream responseBody = exchange.getResponseBody();
responseBody.write("<!DOCTYPE html><html><body><h1>My Response Header</h1><p>And some sample data.</p></body></html>".getBytes());
responseBody.close();
}
exchange.close();
} // end public void handle()
} // end class
I did find something that seems to work although I am not sure if it is the correct way to be handling this. This is not extensively tested, but it does make it shutdown faster.
I replaced:
server.setExecutor(Executors.newCachedThreadPool());
With:
ExecutorService excu = Executors.newCachedThreadPool();
server.setExecutor(excu);
Then just before the server.stop(0); I added excu.shutdown();