SocketTimeoutException Spring 4 - spring-mvc

I am using spring MVC 4 with tomcat 8. while uploading file I am receiving following error. I have configured session to expire after an hour.Can anyone guide me in right direction
Could not parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. null] with root cause
java.net.SocketTimeoutException
at org.apache.tomcat.util.net.NioBlockingSelector.read(NioBlockingSelector.java:201)
at org.apache.tomcat.util.net.NioSelectorPool.read(NioSelectorPool.java:235)
at org.apache.tomcat.util.net.NioSelectorPool.read(NioSelectorPool.java:216)
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1233)
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1182)
at org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:708)
at org.apache.coyote.http11.Http11InputBuffer.access$300(Http11InputBuffer.java:40)
at org.apache.coyote.http11.Http11InputBuffer$SocketInputBuffer.doRead(Http11InputBuffer.java:1057)
at org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:139) ...
In controller :
#PostMapping(value = "/uploadSurvey")
#ResponseBody
public String uploadSurvey(#Valid FileBucket fileBucket, BindingResult result, HttpSession session) {
if (result.hasErrors())
return "redirect:/surveys/uploadSurvey";
else {
byte[] bytes;
try {
bytes = fileBucket.getFile().getBytes();
String decoded = new String(bytes, "UTF-8");
//Here I do object mapping using jackson
}
catch (Exception e){
e.printStackTrace();
}
}
return "xxx";
}
on client side i am using angularjs to send the file:
fd.append('file', file);
fd.append($scope.csrfParamName, $scope.csrfToken);
$http.post(uploadUrl, fd, {
transformRequest : angular.identity,
headers : {
'Content-Type' : undefined
}
})

Related

How does Unity receive http request?

I want to accept http request to order prefab move, so how to receive http request in unity 3D?
If you mean you want to build a web service in your Unity app.
RESTful-Unity is an easy-to-use plugin.
Define the api routing
RoutingManager routingManager = new RoutingManager();
routingManager.AddRoute(new Route(Route.Type.POST, "/path/to/call", "PrefabInvoke.Move"));
Create an Invoke to response the request
namespace RESTfulHTTPServer.src.invoker
{
public class PrefabInvoke : MonoBehaviour
{
public static Response Move(Request request)
{
Response response = new Response();
string responseData = "";
string json = request.GetPOSTData();
bool valid = true;
UnityInvoker.ExecuteOnMainThread.Enqueue (() => {
Debug.Log(json);
try
{
//TODO: Parse Json string and do somthing
response.SetHTTPStatusCode((int)HttpStatusCode.OK);
responseData = "sucess message";
}
catch (Exception ex)
{
valid = false;
string msg = "failed to deseiralised JSON";
responseData = msg;
}
});
// Wait for the main thread
while (responseData.Equals("")) {}
// Filling up the response with data
if (valid) {
// 200 - OK
response.SetContent(responseData);
response.SetHTTPStatusCode ((int)HttpStatusCode.OK);
response.SetMimeType (Response.MIME_CONTENT_TYPE_JSON);
} else {
// 406 - Not acceptable
response.SetContent("Somthing wrong");
response.SetHTTPStatusCode((int) HttpStatusCode.NotAcceptable);
response.SetMimeType(Response.MIME_CONTENT_TYPE_HTML);
}
return response;
}
}
}

ASP.NET controller gets called repeatedly by firefox if HttpStatusCodeResult has newlines in the description [duplicate]

When I return a StatusDescription with a newline using the HttpStatusCodeResult from ASP.Net MVC 3.0, the connection to my client is forcibly closed. App is hosted in IIS 7.0.
Example controller:
public class FooController : Controller
{
public ActionResult MyAction()
{
return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest, "Foo \n Bar");
}
}
Example client:
using (WebClient client = new WebClient())
{
client.DownloadString("http://localhost/app/Foo/MyAction");
}
Thrown Exception:
System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive.
System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
The behavior is consistent when using curl (curl 7.25.0 (i386-pc-win32) libcurl/7.25.0 zlib/1.2.6)
curl http://localhost/app/Foo/MyAction
curl: (56) Recv failure: Connection was reset
Edit
I ended up using this custom ActionResult to get the desired results.
public class BadRequestResult : ActionResult
{
private const int BadRequestCode = (int)HttpStatusCode.BadRequest;
private int count = 0;
public BadRequestResult(string errors)
: this(errors, "")
{
}
public BadRequestResult(string format, params object[] args)
{
if (String.IsNullOrEmpty(format))
{
throw new ArgumentException("format");
}
Errors = String.Format(format, args);
count = Errors.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Length;
}
public string Errors { get; private set; }
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
HttpResponseBase response = context.HttpContext.Response;
response.TrySkipIisCustomErrors = true;
response.StatusCode = BadRequestCode;
response.StatusDescription = String.Format("Bad Request {0} Error(s)", count);
response.Write(Errors);
response.End();
}
}
You can't have a linebreak in the middle of an HTTP header.
The HTTP protocol specifies the end of a header is a line break.
Since the line break is in the middle of a header, the header is not a valid header and you are getting this error.
Fix: Don't put a line break in the middle of an HTTP header.

Postman throwing 400 Bad request for multipart/form-data image upload with jersey 2.0

REQUEST :
URL: http://localhost:8080/RESTfulExample/rest/file/upload
METHOD : POST
HEADER: Content-Type : multipart/form-data
RESPONSE :
HTTP Status 400 - Bad Request
The same code is working with html forms but in postman it's throwing 400 BAD REQUEST, I looked up on google for solution and found that boundary is missing, How to resolve it ? As I have to recieve files from multiple clients like mobile application and web clients via Jquery and rest client.
#Path("/file")
public class UploadFileService {
#POST
#Path("/upload")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(#FormDataParam("file") InputStream uploadedInputStream,
#FormDataParam("file") FormDataContentDisposition fileDetail) {
try {
String uploadedFileLocation = "/home/nash/" + fileDetail.getFileName();
// save it
writeToFile(uploadedInputStream, uploadedFileLocation);
String output = "File uploaded to : " + uploadedFileLocation;
System.out.println("File uploaded..........");
return Response.status(200).entity(output).build();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Exception " + e);
return null;
}
}
// save uploaded file to new location
private void writeToFile(InputStream uploadedInputStream, String uploadedFileLocation) {
try {
OutputStream out = new FileOutputStream(new File(uploadedFileLocation));
int read = 0;
byte[] bytes = new byte[1024];
out = new FileOutputStream(new File(uploadedFileLocation));
while ((read = uploadedInputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Please follow these steps:
Add jersey-multipart dependency.
In Your Application Class (or in web.xml) enable MultipartFeature.class.
DO NOT Add Content-Type header in your postman request.
For me the above steps worked. Do let me know if that helped you or not.

InputStream closed unexpectedly while using Jersey MultiPart file upload & Server-Sent Events (SSE)

I'm using Jersey Multipart for uploading file to the server via Rest API. In the resource method, I accessed the file content via InputStream. I want to return the uploaded file size to the client with EventOutput using SSE so the client easily get the uploaded file size directly from upload resource method.
I'm using Jersey as JAX-RS implementation in java with Grizzly Http server. Here is my code:
#POST
#Path("upload")
#Produces(SseFeature.SERVER_SENT_EVENTS)
#Consumes("multipart/form-data;charset=utf-8")
public EventOutput upload(#FormDataParam("file") InputStream file,
#FormDataParam("file") FormDataContentDisposition fileDisposition) {
final EventOutput eventOutput = new EventOutput();
try {
new Thread(new Runnable() {
#Override
public void run() {
try {
int read = -1;
byte[] buffer = new byte[1024];
OutboundEvent.Builder eventBuilder
= new OutboundEvent.Builder();
OutboundEvent event = null;
long totalRead = 0, lastReadMB = 0;
while ((read = file.read(buffer)) != -1) {
totalRead += read;
if (lastReadMB != (totalRead / (1024 * 1024))) {
lastReadMB = totalRead / (1024 * 1024);
event = eventBuilder.name("uploaded").data(Long.class, totalRead).build();
eventOutput.write(event);
}
}
event = eventBuilder.name("uploaded").data(Long.class, totalRead).build();
eventOutput.write(event);
} catch (Exception e) {
throw new RuntimeException(
"Error when writing the event.", e);
} finally {
try {
eventOutput.close();
} catch (Exception ioClose) {
throw new RuntimeException(
"Error when closing the event output.", ioClose);
}
}
}
}).start();
return eventOutput;
} catch (Exception e) {
logger.error(e.toString(), e);
}
throw new WebApplicationException(Response.status(Response.Status.INTERNAL_SERVER_ERROR).
entity("something happened").build());
}
​
The problem is when my resource method return EventOutput as a response and request processing thread back to the I/O container, the InputStream closed and the processing thread can't access to the uploaded file. Here is the exception:
Exception in thread "Thread-1" java.lang.RuntimeException: Error when writing the event.
at com.WebService.ContentService$1.run(ContentService.java:192)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.jvnet.mimepull.MIMEParsingException: java.io.IOException: Stream Closed
at org.jvnet.mimepull.WeakDataFile.read(WeakDataFile.java:115)
at org.jvnet.mimepull.DataFile.read(DataFile.java:77)
at org.jvnet.mimepull.FileData.read(FileData.java:69)
at org.jvnet.mimepull.DataHead$ReadMultiStream.fetch(DataHead.java:265)
at org.jvnet.mimepull.DataHead$ReadMultiStream.read(DataHead.java:219)
at java.io.InputStream.read(InputStream.java:101)
at com.WebService.ContentService$1.run(ContentService.java:181)
... 1 more
Caused by: java.io.IOException: Stream Closed
at java.io.RandomAccessFile.seek0(Native Method)
at java.io.RandomAccessFile.seek(RandomAccessFile.java:557)
at org.jvnet.mimepull.WeakDataFile.read(WeakDataFile.java:112)
... 7 more
​
1- What's the problem in the code? Why InputStream is closed in the middle of the file transfer?
2- Is there any alternative way to return the uploaded file size to the client in server side? (REQUIREMENT: the upload resource method must handle upload file asynchronously in different thread)

Handling MaxUploadSizeExceededException with Spring MVC

How can I intercept and send custom error messages with file upload when file size is exceeded. I have an annotated exception handler in the controller class, but the request does not come to the controller. The answer I came across on this link How to handle MaxUploadSizeExceededException suggests implementing HandlerExceptionResolver.
Have things changed in Spring 3.5 or is that still the only solution?
I ended up implementing HandlerExceptionResolver:
#Component public class ExceptionResolverImpl implements HandlerExceptionResolver {
private static final Logger LOG = LoggerFactory.getLogger(ExceptionResolverImpl.class);
#Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object obj, Exception exc) {
if(exc instanceof MaxUploadSizeExceededException) {
response.setContentType("text/html");
response.setStatus(HttpStatus.REQUEST_ENTITY_TOO_LARGE.value());
try {
PrintWriter out = response.getWriter();
Long maxSizeInBytes = ((MaxUploadSizeExceededException) exc).getMaxUploadSize();
String message = "Maximum upload size of " + maxSizeInBytes + " Bytes per attachment exceeded";
//send json response
JSONObject json = new JSONObject();
json.put(REConstants.JSON_KEY_MESSAGE, message);
json.put(REConstants.JSON_KEY_SUCCESS, false);
String body = json.toString();
out.println("<html><body><textarea>" + body + "</textarea></body></html>");
return new ModelAndView();
}
catch (IOException e) {
LOG.error("Error writing to output stream", e);
}
}
//for default behaviour
return null;
}
}

Resources