I am writing a Client-Server Application. I am using CloseableHttpClient on the client side for sending GET requests. I want to send 5 GET requests to the server. However, only I am getting response for only first two requests.
Here is my client code :
import java.io.IOException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
public class Test {
public static void main(String[] args) {
HttpGet getreq = new HttpGet("http://shalakha:8089/Gateway/ReverseInvokeListener");
CloseableHttpClient c1 = HttpClients.createMinimal();
try {
for(int i=0;i<5;i++){
CloseableHttpResponse resp = c1.execute(getreq);
System.out.println(resp);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Here is the response I am getting :
HTTP/1.1 200 OK [Server: Apache-Coyote/1.1, Set-Cookie: JSESSIONID=0D4ABDC362FEC3030A5EE3709F3096FD; Path=/Gateway, CLIENTREQ: NO, Content-Length: 0, Date: Thu, 09 Apr 2015 09:22:22 GMT]
HTTP/1.1 200 OK [Server: Apache-Coyote/1.1, CLIENTREQ: NO, Content-Length: 0, Date: Thu, 09 Apr 2015 09:22:26 GMT]
where 'CLIENTREQ' is a CUSTOM header that I have added from the server side while sending the response.
Any pointers as to what must be causing this?
The connectionTimeout in server.xml is set to '-1' which indicates infinite timeout.
Your code has leaked all connections available to it (which are two by default) and has exhausted the connection pool. You need to close response objects to ensure that connections get released back to the pool.
http://hc.apache.org/httpcomponents-client-4.4.x/tutorial/html/fundamentals.html#d5e145
Related
The WebSocket server is a online testing one
The Website
Something goes wrong And I don't know how to fix it.
val client = HttpClient(CIO) { install(WebSockets) }
GlobalScope.launch {
client.webSocket("ws://82.157.123.54:9010/ajaxchattest") {}
}
the error printStackTrace
java.lang.IllegalStateException: Failed to parse request body: request body length
should be specified,
chunked transfer encoding should be used or
keep-alive should be disabled (connection: close)
not knowing how to enable encoding or disable keep-alive or specify body length.
The 82.157.123.54:9010/ajaxchattest endpoint responds with 403 Forbidden instead of 101 Switching Protocols if the Origin header is absent or invalid. So to make it work just append the Origin header with a well-formed value:
val client = HttpClient(CIO) { install(WebSockets) }
client.webSocket("ws://82.157.123.54:9010/ajaxchattest", request = {
header(HttpHeaders.Origin, "http://example")
}) {}
Having this as my sketch, the serial monitor saying that the JSON is successfully sent. But it does not reflect to my Cloud DB.
I changed my HTTPS to HTTP but no luck. Where could this go wrong?
My objective is all input in my Arduino will be sent to my server and store to my Cloud DB.
EDIT: After replacing all suggested Edits, I am getting 400 Bad request.
In Postman, the request is working so i know that my request is valid. But I can't make it work in arduino using ethernet shield
void setup() {
Serial.begin(9600);
// initialize the Ethernet shield using DHCP:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to obtaining an IP address using DHCP");
while(true);
}
delay(1000);
Serial.println("connecting...");
if (client.connect(HOST_NAME, HTTP_PORT)) {
Serial.println("connected");
} else {
Serial.println("connection failed");
}
//Create JSON doc and write a "name" attribute
const size_t capacity = JSON_OBJECT_SIZE(3);
DynamicJsonDocument doc(capacity);
doc["tank_id"] = "2a";
doc["branch_name"] = "aurora";
doc["water_level"] = "high level";
//POST request
Serial.println("Begin POST Request");
client.println("POST /myURL HTTP/1.1");
Serial.println("POST /myURL HTTP/1.1");
client.println("Host: host.net");
Serial.println("Host: host.net");
client.println("User-Agent: Arduino/1.0");
Serial.println("User-Agent: Arduino/1.0");
client.println("Content-Type: application/json");
Serial.println("Content-Type: application/json");
client.println("Connection: keep-alive");
Serial.println("Connection: keep-alive");
client.print("Content-Length: ");
Serial.print("Content-Length: ");
client.println(measureJson(doc));
Serial.println(measureJson(doc));
client.println();
Serial.print(F("Sending: "));
serializeJson(doc, Serial);
Serial.println();
//This works like client.println, but prints doc to client
serializeJsonPretty(doc, client);
//To let me know that request has been completed
Serial.println("Sent POST Request");
while (client.available()) {
char c = client.read();
Serial.print(c);
}
}
void loop() {
while(client.connected()) {
if(client.available()){
// read an incoming byte from the server and print it to serial monitor:
char c = client.read();
Serial.print(c);
}
}
}
I had exactly the same issue... after hours and hours of trying different codes, I found the problem:
serializeJsonPretty(doc, client);
This code, prints this:
POST /api/ HTTP/1.1
Host: api.xxxxxxx.com
Content-Type: application/json
Connection: close
Content-Length: 63
->
-> {
-> "data": "2a",
-> "branch_name": "aurora",
-> "water_level": "high level"
-> }
But, if you change to serializeJson(doc, client); you'll send an HTTP like this:
POST /api/ HTTP/1.1
Host: api.xxxxxxx.com
Content-Type: application/json
Connection: close
Content-Length: 63
->
-> {"data":"2a","branch_name":"aurora","water_level":"high level"}
I understood that the problem is to send the data in each line.. for me, changing data for only one line, the problem is gone.
I hope to help!
Given the following entities, when I "post" a new entity of "TrainerProfile" and miss some of the #NotNull parameters in "Location", I get a 500 together with a stack trace packed into the JSON instead of a 400 and useful information on what went wrong.
#Entity
public class TrainerProfile {
...
#NotNull
#OneToOne(cascade = CascadeType.ALL)
private Location location;
}
#Entity
public class Location {
#Id #GeneratedValue
private Long id;
#NotNull
private String zipcode;
#NotNull
private String city;
#NotNull
private String country;
}
When I post this data to the API
{
...
"location": {
"zipcode": "10000"
}
}
I see the following logs:
javax.validation.ConstraintViolationException: Validation failed for classes [training.edit.provider.model.Location] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='must not be null', propertyPath=city, rootBeanClass=class training.edit.provider.model.Location, messageTemplate='{javax.validation.constraints.NotNull.message}'}
ConstraintViolationImpl{interpolatedMessage='must not be null', propertyPath=country, rootBeanClass=class training.edit.provider.model.Location, messageTemplate='{javax.validation.constraints.NotNull.message}'}
]
But the REST client sees this:
< HTTP/1.1 500
< Vary: Origin
< Vary: Access-Control-Request-Method
< Vary: Access-Control-Request-Headers
< Access-Control-Allow-Origin: http://localhost:4200
< Access-Control-Allow-Credentials: true
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Tue, 16 Jun 2020 09:33:16 GMT
< Connection: close
<
{"timestamp":"2020-06-16T09:33:16.605+0000","status":500,"error":"Internal Server Error","message":"Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction","trace":"org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction\n\tat org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:543)\n...
The text is way longer but I spare you the rest.
I configured validation like this:
#Configuration
#RequiredArgsConstructor(onConstructor = #__(#Autowired))
public class RestConfiguration implements RepositoryRestConfigurer {
private final #NonNull Validator validator;
private final #NonNull UriToIdConverter converter;
#Override
public void configureConversionService(ConfigurableConversionService conversionService) {
RepositoryRestConfigurer.super.configureConversionService(conversionService);
conversionService.addConverter(converter);
}
#Override
public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
validatingListener.addValidator("afterCreate", validator);
validatingListener.addValidator("beforeCreate", validator);
validatingListener.addValidator("afterSave", validator);
validatingListener.addValidator("beforeSave", validator);
}
}
How can I get a proper error message in this case? When I post something that doesn't work for "TrainerProfile" then I get a proper message and error code, but not for the nested object.
Intermediate Solution
Each Spring Data REST request issue a transaction. The outter exception RollbackException gives you a 500 response, even though this exception actually comes from nested validation failure ConstraintViolationException. An working but not nice solution should be have a ResponseEntityExceptionHandler to extract the nested exception, as the auth0 example. The code is here.
Suggestion
Just don't use Spring Data REST where it doesn't fit your requirements.
as said by Spring Data REST leader Oliver Drotbohm in this answer.
A RESTful API should work for aggregate. Aggregate is a DDD concept. Aggregate doesn't work well with relational database. Try No-SQL database such as Mongo DB. The starting point to learn DDD is Oliver's talk.
I am attempting to add multiple Allow Headers to the HttpResponse in aspnetcore v1.1.2. When I run the code below, the headers are added to the IHeaderDictionary on the HttpResponse, however only the last header (in this case "POST") in the collection is actually added to the http response when serialized. Has anyone else experienced this, or am I doing something wrong??
Here is the code I am using.
public override async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
context.HttpContext.Response.Headers.Add("Allow", new StringValues(new [] {"GET", "POST"}));
await next();
}
I am doing this within a ResultFilterAttribute.
Many Thanks...
This should fix the issue:
context.HttpContext.Response.Headers.Add("Allow", "GET, POST");
Your code is fine, the only place that you may need to change is your response parsing logic. Double check your response - it contains 2 Allow headers, not one header with 2 values:
Allow: GET
Allow: POST
Simple example:
Lets say you have next controller action:
[Route("api/[controller]")]
public class ValuesController : Controller
{
// GET api/values
[HttpGet]
[AddHeader]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
Get request using curl:
curl -X GET http://localhost:5000/api/values -i
Response:
HTTP/1.1 200 OK
Date: Fri, 23 Jun 2017 22:23:24 GMT
Content-Type: application/json; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked
Allow: GET
Allow: POST
["value1","value2"]
I have the following code, deployed on a https Asp site, build with MVC 4.0:
public FileResult ANotSoWorkingFunction(string filePath, string fileName)
{
pathToFile = string.Format("~/{0}/{1}", pathToFile, fileName);
return File(new FileStream(pathToFile, FileMode.Open), "application/pdf", fileName);
}
This will work (as you many of you probably already guessed) with Chrome, Firefox and IE9. But it will throw a:
---------------------------
Windows Internet Explorer
---------------------------
Internet Explorer cannot download someFileName from a_site.com.
Internet Explorer was not able to open this Internet site. The requested site is either unavailable or cannot be found. Please try again later.
---------------------------
OK
---------------------------
On IE6,7,8
Any ideas or clues on this one are greatly appreciated as I already spend the hole day playing with html header.
EDIT:
Here are the header from IE7:
HTTP/1.1 200 OK
Cache-Control: private, no-cache="Set-Cookie"
Content-Type: application/pdf
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXAUTH=; expires=Mon, 11-Oct-1999 21:00:00 GMT; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Wed, 04 Apr 2012 08:43:50 GMT
Content-Length: 233324
And here are the ones from IE9:
HTTP/1.1 200 OK
Cache-Control: private, no-cache="Set-Cookie"
Content-Type: application/pdf
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXAUTH=; expires=Mon, 11-Oct-1999 21:00:00 GMT; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Wed, 04 Apr 2012 08:42:14 GMT
Content-Length: 233324
Thank you,
I think I also ran into your problem.
I am also running IIS 7.5 and downloading a PDF through an action on an HTTPS request. For reasons I have yet to isolate, IIS 7.5 seems to be appending no-cache="Set-Cookie" to my Cache-Control response header regardless of what I set the Cache settings to on the Response. This was causing the fairly well documented no-cache issue on IE6, IE7, and IE8.
To resolve this, I made a small wrapper around the FileContentResult that cleared the headers, called the parent, then set the Cacheability to 'Private'. This side-stepped IIS 7.5's insistence to add no-cache="Set-Cookie" to the header, and the file downloaded properly in all browsers I tested. If you want to emulate what I did, first, here's my FileContentResult wrapper.
public class PdfContentResult : FileContentResult {
public PdfContentResult(byte[] data) : base(data, "application/pdf") { }
public PdfContentResult(byte[] data, string fileName) : this(data) {
if (fileName == null) {
throw new ArgumentNullException("fileName");
}
this.FileDownloadName = fileName;
}
public override void ExecuteResult(ControllerContext context) {
context.HttpContext.Response.ClearHeaders();
base.ExecuteResult(context);
context.HttpContext.Response.Cache.SetCacheability(HttpCacheability.Private);
}
}
Then I added an extension method to my ControllerExtensions so that it would be simple to find:
public static class ControllerExtensions {
public static PdfContentResult Pdf(this Controller controller, byte[] fileContents, string fileName) {
return new PdfContentResult(fileContents, fileName);
}
}
Finally, within the Action, I did the equivalent of this:
public ActionResult MyGeneratedPdf() {
byte[] myPdfContentInByteStream = GetPdfFromModel();
return this.Pdf(myPdfContentInByteStream, "MyFile.pdf");
}
Obviously, if you're downloading all kinds of data types, you might not want to bind the workaround so closely to PDF.
We resolved this by changing the cache-control header before streaming the file.
Simplified code sample:
var browserInformation = Request.Browser;
//Set as private if current browser type is IE
Response.AppendHeader("cache-control",
browserInformation.Browser == "IE" ? "private" : "no-cache");
return File(fileName, contentType, downloadFileName);
This worked (yay).. BUT I was left with a lack of clarity on why we had to do it this way for that specific site. We have four websites running on the same box, all under SSL, and only one had this header problem. I compared the web.config files and looked at the setup in IIS but couldn't shed any further light on why that one site needs those headers set explicitly.
If anyone has more to add on the above (for added clairty) that would be great.
In older versions of IE if a user tries to download a file over a HTTPS connection, any response headers that prevent caching will cause the file download process to fail. Below are most common headers which are causing the issue:
Cache-Control with the values no-cache or no-store
Vary with any value
Pragma with value no-cache
You can create an ActionFilterAttribute which will clear cache headers for you like this:
public class ClearCacheHeadersAttribute : FilterAttribute, IActionFilter
{
public void OnActionExecuted(ActionExecutedContext filterContext)
{
return;
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpContext.Current.Response.Headers.Remove("Cache-Control");
HttpContext.Current.Response.Headers.Remove("Vary");
HttpContext.Current.Response.Headers.Remove("Pragma");
//Set the cache headers any way you like keeping in mind which values can brake the download
}
}
And decorate yoour action with it:
[ClearCacheHeaders]
public FileResult ANotSoWorkingFunction(string filePath, string fileName)
{
pathToFile = string.Format("~/{0}/{1}", pathToFile, fileName);
return File(new FileStream(pathToFile, FileMode.Open), "application/pdf", fileName);
}