I am calling API inside the for loop. I want to return response for every time loop was ran. for that I create list of Response object but it started throwing Http 500 error.
so if jsonArray.size() is value is 3 I want to call API 3 times. Everytime it is returning response object. I want to create array of response and return it to client. But it throws exception.
#GET
public Response callAPI() {
Client client=ClientBuilder.newClient();
WebTarget webTarget = client.target(baseUrl);
Response response=null;
for (int i = 0; i < jsonArray.size(); i++)
{
response = webtarget.path("bots").path(/api/dynamicEntity).path(i)
.path("dynamicEntities").request().header("Authorization", "Bearer " + ConnectionUtil.getToken())
.get(Response.class);
}
return response;
}
This code works file. I actually want to return array of response. so if I create Response []response and store the result in array and return it, it throws something called marshal exception.I want to store output of this into Array of response and send it to postman.
I guess your problem is with the server side trying to parse the response array before send to client, and failing, because you can't send a array of Response, the response for an http request can be just one, what you can do is, mount a json object with the response of each request inside the loop, then send the json string inside of a Response object back to the client.
Related
I've been working on a react app. In this app, I will be sending the input from the user to the Java servlet on the tomcat server to sort it. After sorting, I'm trying to display it on a label in my react app. I've successfully sent it to the java servlet using fetch method() and sorted it.
This is how my fetch() method looks like:
const [text, setText] = useState("");
async function onSubmit() {
var newText = { text: text}; //object
await fetch(`http://localhost:8080/backend/link`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Credentials" : true,
"status" : 200
},
body: JSON.stringify(newText),
mode: 'no-cors',
})
.then((response) => {
console.log("response");
console.log(response.body); //displays null
})
.then((data) => {
console.log(data);
console.log("Success");
});
}
My Java servlet looks like this:
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException
{
System.out.println("invoked");
String jsonBody = new BufferedReader(new InputStreamReader(request.getInputStream())).lines().collect(
Collectors.joining("\n"));
System.out.println(jsonBody);
if (jsonBody == null || jsonBody.trim().length() == 0) {
return;
}
JSONObject jObj;
try {
jObj = new JSONObject(jsonBody);
String lines[] = ((String) jObj.get("text")).split(","); //The words in the input are separated by comma
Arrays.sort(lines);
for (String a : lines)
System.out.println(a);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
} catch (JSONException e) {
System.out.print("Exception");
}
}
whatever I send in the response object (Using Printwriter), the fetched response's body is null.
How can I send the array so that I can get it in the response object of the fetch and then display it in a label?
Please leave your suggestions
I do not see where you write the body in the servlet response.
Perhaps you need something like this:
final PrintWriter writer = response.getWriter();
for (String a : lines)
writer.println(a);
Note: your client is expecting a JSON object back, so you probably want to write your jObj to the output and not lines of text.
Use google chrome debug to view response headers of your network request. There you can see the body of the response. My guess is that your client-side code is fine and the server is not sending any content in the body.
From your code it's not clear how did you use PrintWriter. You can try something like below and then check the response:
String message = new ArrayList<String>();
PrintWriter writer = response.getWriter();
JSONObject obj = new JSONObject();
obj.put("message",message);
response.setStatus(200);
writer.append(obj.toString());
writer.close();
Put a string message on JSON object to check whether nothing is being passed or only response is not being passed. Call "response.message" to fetch the message on client side.
It was because I used "no-cors" mode in the client side which means that JavaScript cannot access the properties of the resulting response. Here's a detailed explanation about it: https://stackoverflow.com/a/43319482/13893049 .
I've done several modifications on the client side as well as the server side including changing the content type from application/json to text/plain since json format is not among one of the allowed types.
The only allowed values for the Content-Type header are:
application/x-www-form-urlencoded
multipart/form-data
text/plain
Now my client side code looks like this:
var newText = { text: text, commands: new_list.join(), reg: reg };
await fetch(`http://localhost:8080/backend/link`, {
method: "POST",
headers: {
"Content-Type": "text/plain",
"Origin" : "http://localhost:3000/",
},
body: JSON.stringify(newText),
})
.then((response) => response.text())
.then((data) => {
//console.log("Success");
//console.log(typeof data);
setRes(regex(data));
});
}
(I've added few variables for my requirement)
From the server side I'm sending back an array in the form of string.
I'm answering my own question since someone in the future might find in helpful. Do let me know in the comments if you got any doubts.
This question already has answers here:
How can I upload files to a server using JSP/Servlet?
(14 answers)
Closed 1 year ago.
I'm developing a Backend application using Java and Servlet.
I'm using Postman to simulate my client that will send me POST requests.
The thing is, my Client will send me data (key and value) using the HTTP Body part rather than params. On postman I can simulate it filling KEY and VALUE on the Body part as form-data. On the server side, people recommend this:
String login = request.getParameter("login");
But since the client is sending the parameters to me using the body, the above function returns me null (only works if I use params tab on Postman, which is not my client behavior). I was able to read the body using:
String line = null;
while ((line = request.getReader().readLine()) != null)
System.out.println(line);
But the data I get is like:
----------------------------655577064367924555315251
Content-Disposition: form-data; name="login"
matheus
Which means that I'd have to parse that string to transform it on a map<String,String>, which I'm pretty sure that it's not the best whey to handle it.
There is any way that I can pass a KEY("login") to retrieve the VALUE(matheus) from the Body as made on params?
*** SOLUTION ***
It was missing the annotation:
#MultipartConfig
you can do it like this;
#PostMapping("/")
public #ResponseBody
String greetingPost(HttpServletRequest httpRequest) throws Exception {
final StringBuffer ret = new StringBuffer();
httpRequest.getParts().stream().forEach(part -> {
try {
ret.append(part.getName())
.append(":")
.append(IOUtils.toString(part.getInputStream(), "UTF8"))
.append("\n");
} catch (IOException e) {
e.printStackTrace();
}
});
return ret.toString();
}
I'm facing an issue with handling POST request using Java 11 embedded library java.net.
Client side:
I have two methods in my QueryGenerator class:
public String postTeachers(String newTeachersList) {
this.customRequest = HttpRequest.newBuilder()
.uri(URI.create("http://" + serverIPport + "/" + postTeachers))
.POST(HttpRequest.BodyPublishers.ofString(newTeachersList))
.build();
return getResponseResults();
}
It is used to create a post request.
And also I have a getResponseResults() method
private String getResponseResults() {
String result = null;
try {
CompletableFuture<HttpResponse<String>> response = CustomHttpClientSingleton.getInstance().sendAsync(customRequest, HttpResponse.BodyHandlers.ofString());
result = response.thenApply(HttpResponse::body).join();
} catch(RuntimeException e) {
System.out.println("Seems like the server may not be working properly! Restart it");
}
return result;
}
Server side:
I have a method handlePostRequest
private void handlePostRequest(HttpExchange httpExchange) throws IOException {
Headers headers = httpExchange.getResponseHeaders();
httpExchange.sendResponseHeaders(200, 0);
InputStream is = httpExchange.getRequestBody();
System.out.println(is.toString());
is.close();
}
I get the POST Request in my HttpServer, but when I try to display the contents of a request body, I don't get any information. I'm expecting to receive JSON representation of my ArrayList collection, but the only output I get is:
sun.net.httpserver.FixedLengthInputStream
Is there any way to get request body sent by http client inside POST request and use it on the server side by means of Java 11 java.net embedded library.
Thanks to everyone!
You must read Inputstream content, not just apply toString().
See https://www.baeldung.com/convert-input-stream-to-string
It looks like you are not reading input stream properly. Try to read input stream instead of calling toString() on it. Please check How to get an HTTP POST request body as a Java String at the server side?
for more information.
I wrote a method using Jersey API to make a post request to an api. The api requires the data being posted be in JSON format and has requires a Basic Authorization header however when I run the code below and pass the object it results in the following error
java.lang.RuntimeException: Failed : HTTP error code : 405
at com.shumbamoney.yomoney.SendRequest.send(SendRequest.java:40)
.The java code is below.
public String send(TransactionRequestObject tRObject){
Gson gson = new Gson();
Gson gsonBuilder = new GsonBuilder().create();
String jsonRObject = gsonBuilder.toJson(tRObject);
ApiCredentials credentials = new ApiCredentials();
postUrl = credentials.getURL();
AgentCode = credentials.getAgentCode();
Password = credentials.getPassword();
System.out.println(jsonRObject);
// jersey code
try{
Client client = Client.create();
WebResource webResource = client.resource(postUrl);
ClientResponse response = webResource.type("application/json; charset=ISO-8859-1").header(HttpHeaders.AUTHORIZATION, "Basic "+
AgentCode+":"+Password).post(ClientResponse.class, jsonRObject);
if (response.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatus());
}
System.out.println("Output from Server .... \n");
String output = response.getEntity(String.class);
System.out.println(output);
}catch(Exception e){
e.printStackTrace();
}
return "success";
}
Your help is greatly appreciated.
your code did all the things it should: send the request and get the response from the API, so the error doesn't come from your code, it's from the server that you are requesting to.
try using postman to POST to that url, if you still get the 405 error, than you can make sure that the problem is not from ur code.
Thank you everyone for your contributions I really appreciate them. It turns out the issue was on the server that I was requesting to.
I want to send a json response using a netty http server. I use Gson for the json creation. My code looks like that
HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1,
HttpResponseStatus.OK);
response.headers().set(HttpHeaders.Names.CONTENT_LENGTH, 0);
response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "application/json");
JsonObject jsonResponseMessage = new JsonObject();
jsonResponseMessage.addProperty("result", success);
ctx.write(jsonResponseMessage);
response.headers().set(HttpHeaders.Names.CONTENT_LENGTH, jsonResponseMessage.toString().length());
ctx.write(response);
inside channelRead0 method, and
ctx.flush()
inside channelReadComplete method. The problem is that the I never get the response, back, it seems that the request gets stuck and never return a response. I believe it has to do with the content length. Do I need to do something more?
You need to construct a FullHttpResponse or end the HttpReponse by writing a LastHttpContent.
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(here_your_data_as_byte_array));
response .headers().set(CONTENT_TYPE, "application/json");
response .headers().set(CONTENT_LENGTH, response .content().readableBytes());
ctx.write(response );
ctx.flush();