I am developing a Restful Api. I am using laravel as backend (with apache) and for client I am using Android (with volley library for network communications).
In one of my call I have the following:
JsonArrayRequest jsonObjReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d("Response", response.toString());
//PARSE JSON RESPONSE
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}){
#Override
protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
for (Map.Entry<String, String> e: response.headers.entrySet()){
Log.d(e.getKey(), e.getValue());
}
return super.parseNetworkResponse(response);
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> map = new HashMap<String, String>();
map.put("Accept-Encoding","gzip,deflate");
return map;
}
};
As you can see I set Accept-Encoding :gzip,deflate.
When laravel receive the request, the headers exist:
array (
'accept-encoding' =>
array (
0 => 'gzip,deflate',
),
'host' =>
array (
0 => '192.168.1.104',
),
'connection' =>
array (
0 => 'Keep-Alive',
),
'user-agent' =>
array (
0 => 'Apache-HttpClient/UNAVAILABLE (java 1.5)',
),
'cookie' =>
array (
0 => 'laravel_session=,
),
'cookie2' =>
array (
0 => '$Version=1',
),
)
But when android receive the response it doesn't contains Content-Encoding : gzip header, the headers that it contains are:
Transfer-Encoding﹕ chunked
Date﹕ Sun, 21 Sep 2014 15:15:37 GMT
Keep-Alive﹕ timeout=5, max=99
Set-Cookie﹕ laravel_session=
Content-Type﹕ application/json
Connection﹕ Keep-Alive
X-Powered-By﹕ PHP/5.4.9-4ubuntu2.4
Server﹕ Apache/2.2.22 (Ubuntu)
Cache-Control﹕ no-cache
When I do the same request via curl:
curl -I -H 'Accept-Encoding: gzip' url
it return:
HTTP/1.1 200 OK
Date: Sun, 21 Sep 2014 14:46:12 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.4.9-4ubuntu2.4
Cache-Control: no-cache
Set-Cookie: laravel_session=
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Type: text/html; charset=UTF-8
So, summarizing, I set Accept-Encoding:gzip,deflate, the request is receiveb by server with that headers but when response is received by android Content-Encoding doesn't exist. It is not problem of my server because curl works good.
Any suggestion? thanks
EDIT:
I am watching data sent and received using Wireshark between android and my server. I am watching other request a part from that. This other request is made with JsonObjectRequest instead of JsonArrayRequest and with wireshark I can watch the following headers.
Android -> Server
Content-Type: application/json\r\n
Host: 192.168.1.104\r\n
Connection: Keep-Alive\r\n
User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.5)\r\n
[truncated] Cookie: laravel_session=
Cookie2: $Version=1\r\n
Accept-Encoding: gzip,deflate\r\n
Server -> android
Date: Sun, 21 Sep 2014 18:59:15 GMT\r\n
Server: Apache/2.2.22 (Ubuntu)\r\n
X-Powered-By: PHP/5.4.9-4ubuntu2.4\r\n
Cache-Control: no-cache\r\n
[truncated] Set-Cookie: laravel_session=
Vary: Accept-Encoding\r\n
Content-Encoding: gzip\r\n
Connection: Keep-Alive\r\n
Transfer-Encoding: chunked\r\n
Content-Type: text/html; charset=UTF-8\r\n
In this request the response contains Content-Encoding: gzip. The only different between this request and the other is that this request uses JsonObjectRequest instead JsonArrayRequest, so cant ´JsonArrayRequest use Gzip encode?
Related
I'm developing an Android app that supposed to send PUT request to local server and when I try the same request using curl, I get success response, but from the Android app I get error with PUT request, here is the request for both from mobile app and curl, I listened to both requests on my PC using netcat
user#Laptop:~$ nc -l 192.168.1.104 55555
PUT /api/relay/0 HTTP/1.1
Host: 192.168.1.104:55555
User-Agent: curl/7.58.0
Accept: application/json
Content-Length: 31
Content-Type: application/x-www-form-urlencoded
apikey=2E5DE48567FB10F2&value=1
user#Laptop:~$ nc -l 192.168.1.104 55555
PUT /api/relay/0 HTTP/1.1
Accept: application/json
Content-Type: application/json; charset=utf-8
User-Agent: Dalvik/2.1.0 (Linux; U; Android 9; HRY-LX1MEB Build/HONORHRY-LX1MEB)
Host: 192.168.1.104:55555
Connection: Keep-Alive
Accept-Encoding: gzip
Content-Length: 31
apikey=2E5DE48567FB10F2&value=1
here is my android java request
public void jsonRequestVolley(int method, String url, String requestBody) {
RequestQueue queue = Volley.newRequestQueue(context);
JsonObjectRequest jsonRequest = new JsonObjectRequest(
method,
url,
requestBody,
successResponse(),
errorResponse()
)
{
/**
* Passing some request headers
* */
#Override
public Map<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Accept", "application/json");
return headers;
}
};
queue.add(jsonRequest);
}
the working curl command is
curl -X PUT -H "Accept: application/json" http://192.168.1.105:55555/api/relay/0 --data "apikey=2E5DE48567FB10F2&value=1"```
I fixed the header because of local server requirements so, it worked now it look like
PUT /api/relay/0 HTTP/1.1
Accept: application/json
Content-Type: application/x-www-form-urlencoded
User-Agent: Dalvik/2.1.0 (Linux; U; Android 9; HRY-LX1MEB Build/HONORHRY-LX1MEB)
Host: 192.168.1.104:55555
Connection: Keep-Alive
Accept-Encoding: gzip
Content-Length: 31
I added the following to Android code
#Override
public Map<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Accept", "application/json");
return headers;
}
#Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded";
}
all in request code.
I have a Feign Client to get response from External Api.
Below is the code for Feign Client
#FeignClient(name = "demo", url = "http://localhost:8080")
public interface DemoClient {
#RequestMapping(method = RequestMethod.POST, value = "/api/", consumes = "application/json")
public Response getPayANorLOS(#RequestHeader("AUTH_TOKEN") String token, #RequestBody MyRequest reqBodyProp);
}
I am consuming this using below code
try{
Response response =DemoClient.getPayANorLOS(headerProp, reqBodyProp);
}catch (Exception e) {
//we need to log the error
log.error("Unable to get", e.getMessage());
subscriber.onError(e);
}
I always get an exception. I also logged the request and i see the response
---> POST http://localhost:8080/api/ HTTP/1.1
Content-Type: application/json
AUTH_TOKEN: SBAWCS01:ElHfgB9ESd8Du8pIYKHxxPOWkT26GLf4zhmRVk
Content-Length: 365
---> END HTTP (365-byte body)
<--- HTTP/1.1 200 OK (547ms)
connection: close
content-length: 232
content-security-policy: default-src 'self' https; script-src https: 'self'
'unsafe-inline'; connect-src https: 'self'
content-type: application/json
date: Thu, 16 Aug 2018 19:17:08 GMT
server: Apache-Coyote/1.1
strict-transport-security: max-age=31536000; includeSubDomains
vary: Accept-Encoding
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
{"validThru":"11/22","type":"Demo","brand":"TIM"}
<--- END HTTP (232-byte body)
Why I always get Exception. Please Help.
Also the exception is null.
I need to log in ip/api/login with parameters email, password and then I can retrieve data from ip/api/async. So far i can only log in and retrieve first call. On second app is getting SocketTimeoutException
class talkToWebSite extends AsyncTask<String, Void, String> {
protected String doInBackground(String... strings) {
OkHttpClient client = new OkHttpClient();
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
client.interceptors().add(interceptor);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://ip/")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
TraccarApi stackOverflowAPI = retrofit.create(TraccarApi.class);
Call<Login> call1 = stackOverflowAPI.postUser("admin", "admin");
try {
call1.execute();
} catch (IOException e) {
e.printStackTrace();
}
Call<Data> call = stackOverflowAPI.getData();
Response<Data> response = null;
try {
response = call.execute();
} catch (IOException e) {
e.printStackTrace();
}
return response.body().getDataset().getData_latitude() + "";
}
protected void onPostExecute(String result) {
longitiude.setText(result);
}
}
When I am running that code I receive it:
OkHttp: --> GET /api/login?email=admin&password=admin HTTP/1.1
OkHttp: --> END GET
OkHttp: <-- HTTP/1.1 200 OK (73ms)
OkHttp: Date: Sat, 28 Nov 2015 22:19:12 GMT
OkHttp: Content-Type: application/json; charset=UTF-8
OkHttp: Access-Control-Allow-Origin: *
OkHttp: Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
OkHttp: Access-Control-Allow-Methods: GET, POST
OkHttp: Set-Cookie: JSESSIONID=1fk50j768xc0v1w7tb8inf29nc;Path=/api
OkHttp: Expires: Thu, 01 Jan 1970 00:00:00 GMT
OkHttp: Content-Length: 189
OkHttp: Server: Jetty(9.2.14.v20151106)
OkHttp: OkHttp-Selected-Protocol: http/1.1
OkHttp: OkHttp-Sent-Millis: 1448752725041
OkHttp: OkHttp-Received-Millis: 1448752725091
OkHttp: {"success":true,"data":{"name":"admin","language":"","id":1,"map":"","readonly":false,"distanceUnit":"","speedUnit":"","latitude":0.0,"longitude":0.0,"email":"admin","admin":true,"zoom":0}}
OkHttp: <-- END HTTP (189-byte body)
OkHttp: --> GET /api/async/ HTTP/1.1
OkHttp: --> END GET
Thanks in advice.
To retrieve data from post which need authorization I need add it:
String credentials = "login:password";
final String basic = "Basic " +
Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
client.interceptors().add(new Interceptor() {
#Override
public com.squareup.okhttp.Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
Request.Builder requestBuilder = original.newBuilder()
.header("Authorization", basic)
.method(original.method(), original.body());
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
I have a problem using Volley with GSON. There is no error/exception but the result returned by webservice is always null.
This is my webservice setting :
Status
200 OK Show explanation Loading time: 59
Request headers
CSP: active
Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8,id;q=0.6
Response headers
Date: Wed, 24 Jun 2015 02:37:06 GMT
Server: Apache/2.4.10 (Win32) OpenSSL/1.0.1i PHP/5.5.19
X-Powered-By: PHP/5.5.19
Content-Length: 81
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/json; charset=utf-8
I'm sure the webservice is working fine, so the problem is in the Java code.
This is my custom request, taken from here :
#Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
Log.e("gson", "test");
String json = new String(
response.data,
HttpHeaderParser.parseCharset(response.headers));
Response result = Response.success(
gson.fromJson(json, gsonClass),
HttpHeaderParser.parseCacheHeaders(response));
return result;
} catch (UnsupportedEncodingException e) {
Log.e("gson", e.getLocalizedMessage()); //never printed
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
Log.e("gson", e.getLocalizedMessage()); //never printed
return Response.error(new ParseError(e));
}
}
And this is how i call the Volley, the Customer in onResponse is null :
RequestQueue queue = Volley.newRequestQueue(getActivity());
String url = "https://sister-8.tafinance.com/cust_gathering/index.php/customer/get/format/json";
final Map<String,String> header = new HashMap<String, String>();
//header.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
header.put("name", "test1");
header.put("born_date", "1970-06-15 00:00:00.000");
GsonRequest request = new GsonRequest(Request.Method.POST, url, Customer.class, header,
new Response.Listener<Customer>()
{
#Override
public void onResponse(Customer customer) {
txtTest.setText(customer.getName());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
txtTest.setText("" + volleyError.getMessage());
}
}
);
queue.add(request);
Please kindly help me. Thanks a lot for your help.
What kind of web server do you use? Usually underscore is not accepted for http header field name. (born_date (x), Born-Date(o)
Why underscores are forbidden in HTTP header names, https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Field_names)
You can also change settings of web server to accept underscore for http header field name.
(Refer to http://nginx.org/en/docs/http/ngx_http_core_module.html#underscores_in_headers)
I´m making a Web Service, using Java and Glassfish as server.
I´m also using Apache Server for Processing HTTP requests, i.e, when I make a request, I´m able to get the standard informations, like:
HTTP/1.1 200 OK[\r][\n]
Server: GlassFish Server Open Source Edition 4.1 [\r][\n]"
X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.1 Java/Oracle Corporation/1.8)[\r][\n]
Set-Cookie: JSESSIONID=efc5aa919b55321d3aeaf2c9b3b6; Path=/context; HttpOnly[\r][\n]
Content-Type: text/xml; charset=utf-8[\r][\n]
Date: Thu, 07 May 2015 15:26:40 GMT[\r][\n]
Transfer-Encoding: chunked[\r][\n]
WWW-Authenticate: Basic realm="file"[\r][\n]
Content-Language: [\r][\n]
Content-Type: text/html[\r][\n]
Content-Length: 1090[\r][\n]
SOAPAction: ""[\r][\n]
Host: localhost:8080[\r][\n]
Connection: Keep-Alive[\r][\n]
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)[\r][\n]
One Example of a Web Operation that I developed is:
#WebMethod(operationName = "someoperation")
#Produces(MediaType.APPLICATION_XML)
public void makeHappen(#WebParam(name = "req") Object obj,
#WebParam(name = "resp", mode = WebParam.Mode.OUT) Holder<String> response) {
To List of information that I get, I want to add own specifications, like:
--> OperationName: someOperation
HTTP/1.1 200 OK[\r][\n]
Server: GlassFish Server Open Source Edition 4.1 [\r][\n]"
X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.1 Java/Oracle Corporation/1.8)[\r][\n]
Set-Cookie: JSESSIONID=efc5aa919b55321d3aeaf2c9b3b6; Path=/context; HttpOnly[\r][\n]
Content-Type: text/xml; charset=utf-8[\r][\n]
Date: Thu, 07 May 2015 15:26:40 GMT[\r][\n]
Transfer-Encoding: chunked[\r][\n]
WWW-Authenticate: Basic realm="file"[\r][\n]
Content-Language: [\r][\n]
Content-Type: text/html[\r][\n]
Content-Length: 1090[\r][\n]
SOAPAction: ""[\r][\n]
Host: localhost:8080[\r][\n]
Connection: Keep-Alive[\r][\n]
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)[\r][\n]
For WebSphere Application Server:
Refer to the documentation and examples in Sending transport headers with JAX-WS
Here is a short programming example that illustrates how request
transport headers are sent by a JAX-WS Web services client
application:
public class MyApplicationClass {
// Inject an instance of the service's port-type.
#WebServiceRef(EchoService.class)
private EchoPortType port;
// This method will invoke the web service operation and send transport headers on the request.
public void invokeService() {
// Set up the Map that will contain the request headers.
Map<String, Object> requestHeaders = new HashMap<String, Object>();
requestHeaders.put(“MyHeader1”, “This is a string value”);
requestHeaders.put(“MyHeader2”, new Integer(33));
requestHeaders.put(“MyHeader3”, new Boolean(true));
// Set the Map as a property on the RequestContext.
BindingProvider bp = (BindingProvider) port;
bp.getRequestContext().put(com.ibm.websphere.webservices.Constants.REQUEST_TRANSPORT_PROPERTIES, requestHeaders);
// Invoke the web services operation.
String result = port.echoString(“Hello, world!”);
}
}
Here is a short programming example that illustrates how response
transport headers are sent by a JAX-WS Web services endpoint
implementation class:
#WebService
public class EchoServiceImpl implements EchoServicePortType {
// Inject an instance of WebServiceContext so we can retrieve
// the MessageContext for each invocation of this endpoint.
#Resource
WebServiceContext ctxt;
/**
* Default constructor.
*/
public EchoServiceImpl() {
....
}
public String echoString(String input) {
String result = “Echo result: “ + input;
// Retrieve the MessageContext from the injected WebServiceContext.
MessageContext mc = ctxt.getMessageContext();
// Send some headers back in the response message.
Map<String, Object> responseHeaders = new HashMap<String, Object>();
responseHeaders.put("MyHeader1", "This is a string response value");
responseHeaders.put("MyHeader2", new Integer(33));
responseHeaders.put("MyHeader3”, new Boolean(false));
// Set the response header Map on the MessageContext.
mc.put(com.ibm.websphere.webservices.Constants.RESPONSE_TRANSPORT_PROPERTIES, responseHeaders);
return result;
}
}
For GlassFish Application Server:
You can get the javax.xml.ws.WebServiceContext and from it javax.xml.ws.handler.MessageContext. Then add to the MessageContext your headers, something like this:
...
Map<String, List<String>> headers = new HashMap<String, List<String>>();
headers.put("OperationName", someOperation);
messageContext.put(MessageContext.HTTP_REQUEST_HEADERS, headers)
...
Also you can try to append the HTTP header to the request by using this approach:
...
Dispatch<SOAPMessage> dispatch =
service.createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE);
Map<String, List<String>> headers =
new HashMap<String, List<String>>();
headers.put("OperationName", someOperation);
dispatch.getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS,
headers);
...
See Also:
How to modify request headers in a J2EE web application
How to add HTTP header to SOAP Webservice Glassfish