406 Not Acceptable: Spring 3.2 + JSON + AJAX - ajax

Searched tons of sites and even stackoverflow but have not found a solution to this problem. Looks like lot of people have encountered this problem but its seems a unified solution is missing that encompasses all the aspect. Have already spent 1.5 days on it.
I see the method is getting invoked but somewhere #ResponseBody is not getting translated properly. Can someone take a look and let me know what the problem is. I have Uploaded the code on github. Link to source code on github
#RequestMapping(value = "/find_user", method = RequestMethod.GET)
public #ResponseBody List<String> findUser(#RequestParam("term") String name) {
log.info("Search string for user name: " + name);
List<String> users = new ArrayList<String>();
users.add("Sam");
users.add("Dan");
return users;
}
Browser screen shot below with 406 response
Please note: Ah! How painful. This setup works with Spring 3.1.4 and not with 3.2.X

God, it almost kills me. I tried whatever I can, still stuck there. But finally I figured it out. The reason is Spring, download Spring 3.1.1 and replace all the jars with 3.1.1jars, and it works. All your config is good.

I also faced up with a same problem. After debugging Spring I found that ServletPathExtensionContentNegotiationStrategy tries to determine media type based on an extension in the URL. (Probably, because it cannot deduce what media type it should return from Accept header which contained */* in my case.)
So, one of the way to fix this is to rename URL in mapping by replacing .html by .json.

Related

response.sendRedirect(url) in Spring MVC controller to external host actually redirects to local host

I ve done some researches but couldn't find any question or answer that could help me,
so my probleme is as below :
I have a controller that redirects to an external link :
#controller("person")
publi class PersonController(){
#RequestMapping(value="redirect",method=RequestMethod.POST)
public String redirectToExternalLink(params...){
String url = "https://externalHost.com/doSomthing";
response.sendRedirect(url);
}
}
after going through this method, I find my self face to a 404 error Page not Found, when I check the link I ve been redrected to I find :
www.mydomainName.com/doSomthing
As you can see, the external domain name is replaced by mine, I ve tried also this :
response.setHeader("Location",url);
response.sendRedirect(url);
same issue.
is it a configuration that I should do on tomcat ? or there is a way to solve it ?
thanks
Your code
response.sendRedirect(url);
is correct. However, I would double check the url redirected to. I would also run the code in debug mode and check if
response.sendRedirect(url);
is executed in the first place.
Please refer to this question, Redirect to an external URL from controller action in Spring MVC.
If you encounter the common problem.
For my case, it was a network configurations issue (URL rewriting).

ApiController accept the json in POST on the localhost testing server, but not on the production server. Why?

I have been struggling with this for two days. It is so discouraging.
It is a relatively simple api controller:
[HttpPost]
public HttpResponseMessage Save(ReportCreateInputModel model)
{
if (ModelState.IsValid)
{
_service.AddReport(model);
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, model);
return response;
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
Everything works fine when debugging on localhost:xxxx. The model is valid and a new record can be inserted into the database.
But when it is published to the server, I always get a 400: Bad Request. I have tried different browser and am pretty sure it is a server side issue.
Then I tried increase the request size as mentioned in some other posts. But it still cannot work. I could not install remote debugging tool on that server.
Has anyone seen this problem before? Is it something with IIS 6?
I really appreciate any assistance. Thank you!
Update:
It turns out the api POST action is never hit before the Bad Request error is thrown. But why it is fine in local debugging?
Update:
I have added these lines of code in WebApiConfig.cs
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling =
Newtonsoft.Json.PreserveReferencesHandling.Objects;
json.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Ignore;
config.Formatters.Remove(config.Formatters.XmlFormatter);
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
Now in the jqXHR.responseText I have an exception
"$id":"3","Message":"An error has occurred.",
"ExceptionMessage":"This operation requires IIS integrated pipeline mode.",
"ExceptionType":"System.PlatformNotSupportedException",
"StackTrace":" at System.Web.HttpContext.get_CurrentNotification()
at System.Web.HttpContextWrapper.get_CurrentNotification()
at GetCurrentNotification(Object )
at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)"
Wow! Is it something to do with IIS 6 I am using? Who can tell me what that StackTrace is? Thanks.
Now I find out in here that it is get_CurrentNotification that requires the pipeline thing, which exists only in IIS7. But who can tell us where have I made calls to HttpContext.CurrentNotification?
Try changing the code to this instead to see why you are getting a bad request,
return Request.CreateResponse(HttpStatusCode.BadRequest, ModelState);
You should always include ModelState in your response if you are returning a 400 due to invalid ModelState. That way the clients would have information on what is wrong with their request.
Also, if possible, just for debugging, enable IncludeExceptionDetails always by doing this on your configuration. That way you can get more details in your 400 error response.
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
Remember that you should IncludeExceptionDetails always only for debugging on production servers. Otherwise, you would be leaking security sensitive information to everyone who can access your service which is bad.

PHP Kohana 3.2.2 multipart form $_POST not set on MAC but works on Win

I've just encountered a weird problem. I've recently developed a medium size website using Kohana 3.2.2 + jquery + html + WAMP on Windows 7 platform. And everything seems to be working fine, until someone tries accesing the page from Mac platform. It seems that when sending some data with files in multipart form the global variable $_POST is not set, even though when debugging the data in web browser i'm able to see that DATA IS SET :| it's just not accesable by the controller with any $_POST or request->post(). I'm repeating, everything works perfectly when user is accesing page from Windows platform (tested on few separated clients), but not working when accesing from Mac platforms (tested on few separated clients).
It's killing me...
Example of what im trying to do:
In View:
user puts data into inputs (text and file types). Data is being send by form with enctype = multipart/form-data to controller's action
In controller:
$post = request->post();
if($post['sometextinput'] != '') throws exception of unknown index 'sometextinput'.
That's extremely odd. I use Kohana on a daily basis (I develop on a Mac) and have never had an issue like that. Could you post your controller and the view? I'll plug it into a dummy project and see if I can replicate the issue. If I can I'll do what I can to get it working.
EDIT:
Could it possible be an odd configuration issue?
Just for my own clarification.
You're submitting a form that contains input fields and one or more file uploads.
When viewing it on a Windows machine you can see that the data is set in $_POST or $request->post().
On OSX it's not viewable to the controller via $_POST or $request->post();
In your before method make sure you have "parent::before();". If you are already calling parent::before() try putting it as the first statement in your before() method. If that doesn't work try adding it as the last statement. It's a shot in the dark, but it's worth a try.
If you don't have a before() method then add one and call parent::before();.
I'm not sure if you were just in a hurry to type up your example above but it actually should be:
#$post = request->post(); //wouldn't recommend doing this
if($this->request->post('sometextinput') != '') throws exception of unknown index 'sometextinput'.

Why aren't my images caching?

I have an ASP.NET MVC3 application setup. There is a controller that returns back images and I have added the following:
[OutputCache(Duration = 3600, VaryByParam = "id;width", Order = 1000, Location = OutputCacheLocation.Client)]
public ActionResult Get(string id, int width)
{ ... }
But when I check out the HTTP Response on these images they all have headers that say "cache-control: no-cache" and "expires: -1" which means the browser is never caching them.
I'm looking all around and I can't find anything on why the response is telling the browser not to cache them. I even tried working up my own attribute that did:
public class ContentExpiresHeader : ActionFilterAttribute
{
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
var cache = filterContext.HttpContext.Response.Cache;
cache.SetExpires(DateTime.Now.AddYears(1));
cache.SetCacheability(HttpCacheability.Private);
cache.SetLastModifiedFromFileDependencies();
base.OnResultExecuted(filterContext);
}
}
but that didn't get me anywhere either.
Any help is appreciated.
UPDATE: I'm starting to think this has got to be an IIS setting somewhere that is adding the no-cache and overriding. I can't seem to find anything, though. The only odd thing is that if I take a look at the state of the cache variable after I've called the .Set...() methods the internal variables have not been updated. I would have expected something to change but they're still showing "no-cache".
UPDATE 2: I should add that the return of this method is a:
return File(...);
UPDATE 3: I also found this (http://dotnetslackers.com/articles/aspnet/ASP-NET-MVC-3-Controller-for-Serving-Images.aspx) and tried implementing it without any luck. Still getting the no-cache options on the response header for the images.
UPDATE 4: Just had to check server settings... if I bypass my controller and go straight to an image file on the server, then it DOES cache and has the correct caching settings in the response header.
UPDATE 5 (yeah, getting crazy): Created a brand new MVC3 project and just made the one controller and it cached just fine. So I've got something outside the immediate code that is adding this pragma:no-cache stuff and for the life of me I can't figure out what it'd be. =-/
Try changing the cacheability from HttpCachability.Private to HttpCachability.ServerAndPrivate. It should keep the cache-control as private and not suppress e-tags/last modified.
Found the problem! And it's the weirdest thing I've seen in a while.
I am using SocialAuth-net and somewhere during the setup I added the system.webServer module for it and set runAllManagedModulesForAllRequests=true. I thought, "huh, wonder if that's causing it somehow", as I couldn't reproduce the problem outside this particular app. Low and behold, commenting out that section of the config and my images started caching! Hoorah!
But, it gets weirder. I undid my config changes, refreshed and now I'm still getting caching. I can't tell you how many resets of the system I've done with no change but somehow temporarily removing these modules from the pipeline seems to have resolved this problem.
I can track it down to the SocialAuthHttpModule and if I remove it SocialAuth-net still seems to work but caching is restored reliably. Very weird.

GWT + Tomcat Session without Cookies!

I'm working on a web-project which uses GWT on client and Java on server side (tomcat7).
If cookies are enabled on the browser, everything works fine. I can use sessions without any problems.
If cookies are disabled on the browser, sessions doesn't work.
I guess, this his mainly something to do with GWT apps being a single web-page application which only requests data from the server via ajax.
Is there a way to get sessions working under such circumstances?
Help is very appreciated!
All the best,
Thomas
If you using GWT RPC, you will need to modify your RPC urls to burn in the jsessionid as discussed in this forum post. Though I am not sure if line Cookies.getCookie("JSESSIONID") as shown the forum post will work in your case. You might need to parse the location.href
On the server side you can access the session as follows:
public class NameImpl extends RemoteServiceServlet implements NameService {
public void doSomething() throws IllegalArgumentException{
HttpSession hs = this.getThreadLocalRequest().getSession();
//Do whatever it is you want to do with this information.
}
}
Not 100% sure that if is what you are asking for, but it seems like the most reasonable answer.

Resources