How to download and read a text file using Retrofit or even better Rx Retrofit ?
Below is a sample how it was done before retrofit time.
really would be how to convert the code below in Retrofit
Sample:
try {
// Create a URL for the desired page
URL url = new URL("ksite.com/thefile.txt");
// Read all the text returned by the server
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
while ((str = in.readLine()) != null) {
// str is one line of text; readLine() strips the newline character(s)
}
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
I really Appreciate your help. Thanks
Edit:
There is a #Streaming annotation since version Retrofit 1.6 that can be used for delivering a raw InputStream. Can be used for downloading a file.
IMO Retrofit is not the best tool for downloading a file (unless the file contains JSON).
Using Retrofit (version 2) means you are using OkHttp under the hood. OkHttp is the better tool for downloading a file.
An asynchronous get with OkHttp looks like this:
private final OkHttpClient client = new OkHttpClient();
public void run() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
client.newCall(request).enqueue(new Callback() {
#Override public void onFailure(Request request, IOException throwable) {
throwable.printStackTrace();
}
#Override public void onResponse(Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0; i < responseHeaders.size(); i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
System.out.println(response.body().string());
}
});
}
More in the recipes section on Github.
Also from the wiki:
The string() method on response body is convenient and efficient for
small documents. But if the response body is large (greater than 1
MiB), avoid string() because it will load the entire document into
memory. In that case, prefer to process the body as a stream.
Edit:
Using RxJava
public interface Api {
#Streaming
#GET("path to file")
Observable<ResponseBody> getFile();
}
api.getFile()
.flatMap(responseBody -> {
try {
return Observable.just(responseBody.string());
} catch (IOException e) {
return Observable.error(e);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(System.out::println);
Again you should probably not use responseBody.string() for bigger files.
Related
I have searched everywhere but I couldn't find my answer, is there a way to make a simple HTTP request? I want to request a PHP page / script on one of my websites but I don't want to show the webpage.
If possible I even want to do it in the background (in a BroadcastReceiver)
UPDATE
This is a very old answer. I definitely won't recommend Apache's client anymore. Instead use either:
Retrofit
OkHttp
Volley
HttpUrlConnection
Original Answer
First of all, request a permission to access network, add following to your manifest:
<uses-permission android:name="android.permission.INTERNET" />
Then the easiest way is to use Apache http client bundled with Android:
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(new HttpGet(URL));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
String responseString = out.toString();
out.close();
//..more logic
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
If you want it to run on separate thread I'd recommend extending AsyncTask:
class RequestTask extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
responseString = out.toString();
out.close();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//Do anything with response..
}
}
You then can make a request by:
new RequestTask().execute("http://stackoverflow.com");
unless you have an explicit reason to choose the Apache HttpClient, you should prefer java.net.URLConnection. you can find plenty of examples of how to use it on the web.
we've also improved the Android documentation since your original post: http://developer.android.com/reference/java/net/HttpURLConnection.html
and we've talked about the trade-offs on the official blog: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
Note: The Apache HTTP Client bundled with Android is now deprecated in favor of HttpURLConnection. Please see the Android Developers Blog for more details.
Add <uses-permission android:name="android.permission.INTERNET" /> to your manifest.
You would then retrieve a web page like so:
URL url = new URL("http://www.android.com/");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
readStream(in);
}
finally {
urlConnection.disconnect();
}
I also suggest running it on a separate thread:
class RequestTask extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... uri) {
String responseString = null;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
if(conn.getResponseCode() == HttpsURLConnection.HTTP_OK){
// Do normal input or output stream reading
}
else {
response = "FAILED"; // See documentation for more info on response handling
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//Do anything with response..
}
}
See the documentation for more information on response handling and POST requests.
The most simple way is using the Android lib called Volley
Volley offers the following benefits:
Automatic scheduling of network requests. Multiple concurrent network
connections. Transparent disk and memory response caching with
standard HTTP cache coherence. Support for request prioritization.
Cancellation request API. You can cancel a single request, or you can
set blocks or scopes of requests to cancel. Ease of customization, for
example, for retry and backoff. Strong ordering that makes it easy to
correctly populate your UI with data fetched asynchronously from the
network. Debugging and tracing tools.
You can send a http/https request as simple as this:
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.yourapi.com";
JsonObjectRequest request = new JsonObjectRequest(url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
if (null != response) {
try {
//handle your response
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(request);
In this case, you needn't consider "running in the background" or "using cache" yourself as all of these has already been done by Volley.
Use Volley as suggested above. Add following into build.gradle (Module: app)
implementation 'com.android.volley:volley:1.1.1'
Add following into AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
And add following to you Activity code:
public void httpCall(String url) {
RequestQueue queue = Volley.newRequestQueue(this);
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// enjoy your response
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// enjoy your error status
}
});
queue.add(stringRequest);
}
It replaces http client and it is very simple.
private String getToServer(String service) throws IOException {
HttpGet httpget = new HttpGet(service);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
return new DefaultHttpClient().execute(httpget, responseHandler);
}
Regards
With a thread:
private class LoadingThread extends Thread {
Handler handler;
LoadingThread(Handler h) {
handler = h;
}
#Override
public void run() {
Message m = handler.obtainMessage();
try {
BufferedReader in =
new BufferedReader(new InputStreamReader(url.openStream()));
String page = "";
String inLine;
while ((inLine = in.readLine()) != null) {
page += inLine;
}
in.close();
Bundle b = new Bundle();
b.putString("result", page);
m.setData(b);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
handler.sendMessage(m);
}
}
As none of the answers described a way to perform requests with OkHttp, which is very popular http client nowadays for Android and Java in general, I am going to provide a simple example:
//get an instance of the client
OkHttpClient client = new OkHttpClient();
//add parameters
HttpUrl.Builder urlBuilder = HttpUrl.parse("https://www.example.com").newBuilder();
urlBuilder.addQueryParameter("query", "stack-overflow");
String url = urlBuilder.build().toString();
//build the request
Request request = new Request.Builder().url(url).build();
//execute
Response response = client.newCall(request).execute();
The clear advantage of this library is that it abstracts us from some low level details, providing more friendly and secure ways to interact with them. The syntax is also simplified and permits to write nice code.
I made this for a webservice to requerst on URL, using a Gson lib:
Client:
public EstabelecimentoList getListaEstabelecimentoPorPromocao(){
EstabelecimentoList estabelecimentoList = new EstabelecimentoList();
try{
URL url = new URL("http://" + Conexao.getSERVIDOR()+ "/cardapio.online/rest/recursos/busca_estabelecimento_promocao_android");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
if (con.getResponseCode() != 200) {
throw new RuntimeException("HTTP error code : "+ con.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((con.getInputStream())));
estabelecimentoList = new Gson().fromJson(br, EstabelecimentoList.class);
con.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
return estabelecimentoList;
}
Look at this awesome new library which is available via gradle :)
build.gradle: compile 'com.apptakk.http_request:http-request:0.1.2'
Usage:
new HttpRequestTask(
new HttpRequest("http://httpbin.org/post", HttpRequest.POST, "{ \"some\": \"data\" }"),
new HttpRequest.Handler() {
#Override
public void response(HttpResponse response) {
if (response.code == 200) {
Log.d(this.getClass().toString(), "Request successful!");
} else {
Log.e(this.getClass().toString(), "Request unsuccessful: " + response);
}
}
}).execute();
https://github.com/erf/http-request
This is the new code for HTTP Get/POST request in android. HTTPClient is depricated and may not be available as it was in my case.
Firstly add the two dependencies in build.gradle:
compile 'org.apache.httpcomponents:httpcore:4.4.1'
compile 'org.apache.httpcomponents:httpclient:4.5'
Then write this code in ASyncTask in doBackground method.
URL url = new URL("http://localhost:8080/web/get?key=value");
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("GET");
int statusCode = urlConnection.getResponseCode();
if (statusCode == 200) {
InputStream it = new BufferedInputStream(urlConnection.getInputStream());
InputStreamReader read = new InputStreamReader(it);
BufferedReader buff = new BufferedReader(read);
StringBuilder dta = new StringBuilder();
String chunks ;
while((chunks = buff.readLine()) != null)
{
dta.append(chunks);
}
}
else
{
//Handle else
}
For me, the easiest way is using library called Retrofit2
We just need to create an Interface that contain our request method, parameters, and also we can make custom header for each request :
public interface MyService {
#GET("users/{user}/repos")
Call<List<Repo>> listRepos(#Path("user") String user);
#GET("user")
Call<UserDetails> getUserDetails(#Header("Authorization") String credentials);
#POST("users/new")
Call<User> createUser(#Body User user);
#FormUrlEncoded
#POST("user/edit")
Call<User> updateUser(#Field("first_name") String first,
#Field("last_name") String last);
#Multipart
#PUT("user/photo")
Call<User> updateUser(#Part("photo") RequestBody photo,
#Part("description") RequestBody description);
#Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
#GET("users/{username}")
Call<User> getUser(#Path("username") String username);
}
And the best is, we can do it asynchronously easily using enqueue method
I wrote a method that gets JSON, converts an object to java and writes JSON to a file.But writing to the file just does not work. Tell me what could be the reason?
public class ApiUtils {
public static HttpClient client = HttpClient.newHttpClient();
public static void getRequest(String url, String path) {
PostDTO postDTO = new PostDTO();
String pathJSONFile = "src/main/resources/Post.json";
List<PostPojo> postPojos = null;
HttpRequest request = HttpRequest.newBuilder()
.GET()
.header("accept", "application/json")
.uri(URI.create(url + path))
.build();
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
ObjectMapper objectMapper = new ObjectMapper();
postPojos = objectMapper.readValue(response.body(), new TypeReference<List<PostPojo>>() {
});
objectMapper.writeValue(Paths.get("allPost.json").toFile(), response.body());
postDTO.setStatus(response.statusCode());
postDTO.setPosts(postPojos);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(postDTO);
}
}
File allPost.json located in the folder resources.
You're writing the wrong object I think - your code sample says
objectMapper.writeValue(Paths.get("allPost.json").toFile(), response.body());
which is trying to write the InputStream of response.body(). I presume you meant to try and write out postPojos via
objectMapper.writeValue(Paths.get("allPost.json").toFile(), postPojos);
instead.
Volley response is not showing the Arabic character ف
Instead of this character I'm getting a diamond question mark � .
All the other characters are showing properly, I don't know the what is happening with this character alone.Is it the problem of volley web service?
Any help appreciated.
final RequestQueue requestQueue = Volley.newRequestQueue(Register.this);
String url = Config.url + "validateID";
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
response = response.trim();
if (response != null) {
try {
response = new String(response.getBytes(), "UTF-8");
response = Html.fromHtml(response).toString();
response = fixEncodingUnicode(response);
System.out.println("######utf####" + response);
try {
JSONObject jsonObject = new JSONObject(response);
String respCode = jsonObject.getString("responseCode");
String status = jsonObject.getString("status");
if (respCode.equals("200") && status.equals("ACTIVE")) {
ed_full_name.setText(jsonObject.getString("name"));
ed_full_name_arabic.setText(jsonObject.getString("namearabic"));
}
} catch (JSONException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
}
public static String fixEncodingUnicode(String response) {
String str = "";
try {
str = new String(response.getBytes("windows-1254"), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String decodedStr = Html.fromHtml(str).toString();
return decodedStr;
}
I am afraid the patching code from a wrong encoding to a correct encoding cannot guarantee all characters survive the process. The main principle in java is that String always holds Unicode text; so there always is a conversion to bytes representing text in some encoding.
response = new String(response.getBytes(), "UTF-8");
This is wrong. getBytes() without charset uses the default charset from the platform which runs the current application. So it has a different effect on your development Windows PC and the production Linux server. Any effect is totally misleading.
response = Html.fromHtml(response).toString();
This encodes HTML entities. In a request a sign then the <form> is missing an accept-encoding="UTF-8". Part of the request headers. Then the browser sends non-Latin as HTML entities.
Here it might be a communication failure between layers, where the request part is missing a UTF-8 accepting header.
response = fixEncodingUnicode(response); or str = new String(response.getBytes("windows-1254"), "UTF-8");
Unneeded as String in java already is in Unicode. It would introduce a diamond whenever a Unicode symbol was not translatable in Windows-1254.
So all seems wrong. The error seems to be made earlier on.
Correct the requests, as otherwise a correct request might give wrong results. Go for UTF-8 rather than Windows-1254.
You can dump, log the bytes if the input parameter response, with something like:
Arrays.toString(response.codePoints().toArray())
(A hexadecimal format would be more readable.)
As #Joop Eggen said, no need of html and Windows-1254 encoding. Just use the default enocding of Volley that is ISO-8859-1.
response = new String(response.getBytes("ISO-8859-1"), "UTF-8");
complete code is below.
final RequestQueue requestQueue = Volley.newRequestQueue(Register.this);
String url = Config.url + "validateID";
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
response = response.trim();
if (response != null) {
try {
response = new String(response.getBytes("ISO-8859-1"), "UTF-8");
try {
JSONObject jsonObject = new JSONObject(response);
String respCode = jsonObject.getString("responseCode");
String status = jsonObject.getString("status");
if (respCode.equals("200") && status.equals("ACTIVE")) {
ed_full_name.setText(jsonObject.getString("name"));
ed_full_name_arabic.setText(jsonObject.getString("namearabic"));
}
} catch (JSONException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
}
I don't know how to avoid it, i have closed the response body already!
Can someone help me solve this problem?
my code:
public String getPageFromServer(String activityKey) throws Exception {
String address = pageServerHolder.getServerAddressRandom();
String url = MessageFormat.format(URL, address, activityKey);
log.debug("=============== url [{}] ================", url);
OkHttpClient client = new OkHttpClient().newBuilder().connectTimeout(60, TimeUnit.SECONDS).callTimeout(1, TimeUnit.SECONDS).build();
final Request request = new Request.Builder().url(url).get().build();
Response response = client.newCall(request).execute();
try (ResponseBody body = response.body()) {
if (response.isSuccessful() && null != body) {
String bodyString = body.string();
if (StringUtils.isNotBlank(bodyString)) {
body.close();
return bodyString;
}
}
}
throw new RuntimeException(MessageFormat.format("获取活动页信息异常,url [{0}], response.code [{1}],response.message [{2}] ", url, response.code(), response.message()));
}
Your problem is that the Response is not closed. Your code should be something like this:
try (Response response = client.newCall(request).execute();
ResponseBody body = response.body()) {
if (response.isSuccessful() && null != body) {
String bodyString = body.string();
if (StringUtils.isNotBlank(bodyString)) {
return bodyString;
}
}
}
I'm not sure if you need to close the ResponseBody. It is possible that closing response will deal with it. However, there is little harm in a redundant close.
Check out the example here: https://square.github.io/okhttp/
ResponseBody implements the Closeable interface. You are creating ResponseBody in the resource section of the try block, it will be closed for you as you leave the try block.
Your "body.close()" should not be there.
try (Response response = httpClient.newCall(request).execute();
ResponseBody responseBody = response.body()) {
if (response.isSuccessful()) {
log.info("access tree from {} success", url);
return objectMapper.readValue(responseBody.string(), StorageTreeResponse.class);
} else {
return null;
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
I am wondering this is just a bug from okhttp client. Even the try resource syntax didn't solve the warnings.
RestTemplate example is below.
public class SimpleClient {
private final String URL;
private AsyncRestTemplate rest = new AsyncRestTemplate(new Netty4ClientHttpRequestFactory());
private RestTemplate restTemplate = new RestTemplate(new Netty4ClientHttpRequestFactory());
public SimpleClient(String url) {
this.URL = url;
Netty4ClientHttpRequestFactory nettyFactory = new Netty4ClientHttpRequestFactory();
try {
nettyFactory.setSslContext(SslContextBuilder.forClient().build());
} catch (SSLException e) {
e.printStackTrace();
}
rest = new AsyncRestTemplate(nettyFactory);
}
#Override
public ResponseEntity<ResponseData> doSendByPOST(RequestData data,Class<ResponseData> clazz) {
List<HttpMessageConverter<?>> messageConvertors = new ArrayList<>();
messageConvertors.add(new MappingJackson2HttpMessageConverter());
rest.setMessageConverters(messageConvertors);
restTemplate.setMessageConverters(messageConvertors);
HttpHeaders headers = new HttpHeaders();
ObjectMapper objectMapper = new ObjectMapper();
StringWriter writer = new StringWriter();
try {
objectMapper.writeValue(writer, data);
} catch (IOException e) {
e.printStackTrace();
}
headers.set(HttpHeaders.CONTENT_LENGTH,String.valueOf(writer.toString().getBytes(Charset.forName("UTF-8")).length));
headers.set(HttpHeaders.CONTENT_TYPE,"application/json");
HttpEntity<ResponseData> request = new HttpEntity<ResponseData>(headers);
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<String, Object>();
try {
parts.add("requestData", objectMapper.writeValueAsString(data));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
// return restTemplate.exchange(this.URL,HttpMethod.POST ,request, clazz, parts);
ListenableFuture<ResponseEntity<ResponseData>> entity = rest.exchange(this.URL,HttpMethod.POST ,request, clazz, parts);
return extractResponseEntity(entity);
}
// ...
}
Netty read data from request channelRead method
#Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof HttpRequest) {
DefaultHttpRequest defaultHttpRequest = (DefaultHttpRequest) msg;
if (EmptyHttpHeaders.is100ContinueExpected(defaultHttpRequest)) {
ctx.write(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,HttpResponseStatus.CONTINUE));
}
boolean keepAlive = EmptyHttpHeaders.isKeepAlive(defaultHttpRequest);
handle = frontController.dispatchRequest(defaultHttpRequest);
}
if (msg instanceof HttpContent) {
HttpContent httpContent = (HttpContent) msg;
ByteArrayOutputStream body = new ByteArrayOutputStream(64);
ByteBuf content = httpContent.content();
if (content.isReadable()) {
//body.write(content.array());
content.readBytes(body,content.readableBytes());
//body.append(content.toString(CharsetUtil.UTF_8));
FullHttpResponse response = handle.handle(body);
if(response == null){
response = prepareDefaultResponse();
}
response.headers().set("content-type", "application/json");
response.headers().set("content-length", response.content().readableBytes());
response.headers().set("connection", HttpHeaderValues.KEEP_ALIVE);
}
if (msg instanceof LastHttpContent) {
//process request
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
}
}
The code below is working fine but I guess there is a problem with blocking io and nonblocking io. When the request is dispatched, I can not reach the HttpContent I only get HttpRequest as a msg parameter. Spring resttemplate waits for a response but Netty does not care :)
if (msg instanceof HttpRequest) {
DefaultHttpRequest defaultHttpRequest = (DefaultHttpRequest) msg;
if (EmptyHttpHeaders.is100ContinueExpected(defaultHttpRequest)) {
ctx.write(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,HttpResponseStatus.CONTINUE));
}
boolean keepAlive = EmptyHttpHeaders.isKeepAlive(defaultHttpRequest);
handle = frontController.dispatchRequest(defaultHttpRequest);
}
My problem is how to get response from netty server by rest template.
I have tried many ways to accomplish full req/resp.
When restTemplate request to Netty server it hangs the thread so I can not move on the distributed in memory cache implementation.
Hanging in RestTemplate.java Line : 681
Method waits forever when using Netty4ClientHttpRequestFactory.
response = request.execute();
From my understanding, you read HTTP post request that from Rest Client as HttpRequest Object lets call it first case so that means you don't even branch on the if (msg instanceof HttpContent) {} case (second one) your HTTP server just writes the default response without any content or header that you're setting in the second case. If this is the cause for the blocking on the client side you have to fill that default response just like on the second case an see what client do.
I think netty API provides this
https://netty.io/4.1/api/io/netty/handler/codec/http/DefaultFullHttpResponse.html
Also this example could give you an idea of what could be wrong server side.
http://www.seepingmatter.com/2016/03/30/a-simple-standalone-http-server-with-netty.html