Spring MVC detect ajax request - ajax

How to detect an ajax request in the best possible way?
I'm currently using this in my controller:
private boolean isAjax(HttpServletRequest request){
String header = request.getHeader("x-requested-with");
if(header != null && header.equals("XMLHttpRequest"))
return true;
else
return false;
}
But I don't like this way, I think there should have a better solution with Spring.

That is the only "generic" way to detect an Ajax request.
But keep in mind: that's not failproof, it is just a best effort attempt, it is possible to make an Ajax request without sending the X-Requested-With headers.
jQuery usually includes that header. Maybe another lib doesn't. The protocol certainly doesn't consider that header mandatory.
Just a note: Your code is perfectly valid, though you could write it a bit simpler:
private boolean isAjax(HttpServletRequest request) {
String requestedWithHeader = request.getHeader("X-Requested-With");
return "XMLHttpRequest".equals(requestedWithHeader);
}

There is a simple bullet proof solution. Simply send query parameter like ajax=1 from your ajax request and send a different value or do not send this parameter for regular request and check in your controller and take action accordingly.

Related

"the UmbracoHelper was constructed with an UmbracoContext and the current request is not a front-end request."

I'm trying to implement ajax pagination using Umbraco.
On the server side, I have the following:
[System.Web.Http.HttpGet]
public JsonResult pagination(int? page)
{
IEnumerable<IPublishedContent> newsPosts = Umbraco.AssignedContentItem.DescendantOrSelf("news").Children.Where(x => x.IsVisible() && x.DocumentTypeAlias == "newsPost").OrderByDescending(x => x.UpdateDate).Take(5);
//from here on we will be returning the json within which information required for displaying post entries in carousel is included.
string json = "[some random string]"; //just random string for now.
return Json(json, JsonRequestBehavior.AllowGet);
}
As you can see, I'm trying to get necessary data from IPublishedContents, but I'm having trouble instantiating this series of IPublishedContents.
And this is the error I'm getting when I access:
locahost:{port}/umbraco/surface/{controller}/pagination on Chrome.
Cannot return the IPublishedContent because the UmbracoHelper was constructed with an UmbracoContext and the current request is not a front-end request.
Details: System.InvalidOperationException: Cannot return the IPublishedContent because the UmbracoHelper was constructed with an UmbracoContext and the current request is not a front-end request.
As I said, I'm making this request from Chrome, which is I think means this request is from the front end, so I'm not sure why I'm getting this error.
In the course of searching I found these
1) our.umbraco.com forum
2) stackoverflow post
is deserted with no answer, and as for 2, it strikes me that the answer is not quite relevant to my case. I want to instantiate IPublishedContent in the first place.
Mine is Umbraco 7.
and could it be possible to tell me why requests from the front-end are not desirable?
Any hint would be highly appreciated.
Thanks,
Try getting your node this way.
var umbracoHelper = new Umbraco.Web.UmbracoHelper(Umbraco.Web.UmbracoContext.Current);
var yourNode = umbracoHelper.TypedContentAtXPath("umbracoPathtoYourNode");
Perhaps easier to use web api
Create a controller which inherits from UmbracoApiController
public class PagedItemsController : UmbracoApiController
{
[HttpGet]
[ActionName("list")] //Optional see note below
public IHttpActionResult GetItems([FromUri] int pageNo = 1)
{
// Next you need some way of getting the items you need.
// I would not return the whole IPublishedContent items. Rather query those and then use linq Select to transform into a more relevant smaller class (not doing this here)
// I've just included this for brevity
var items = _itemService.GetPagedItems(pageNo);
// Now return the results
return Ok(items);
}
}
Calls to endpoints in Umbraco follow the format
/umbraco/api/{controller}/{endpoint}
With the [ActionName("list")] above the call to the GetItems method will be
http://example.com/umbraco/api/PagedItems/list?pageNo=3
Without the ActionName attribute the call would be
http://exampe.com/umbraco/api/PagedItems/GetItems?pageNo=3
With a standard jquery ajax call this will return json without needing to serialise.

Spring Show Empty Page When Entering GET Url

I have a request map which returns list from database in json. Is it possible if visitor enters the exact url in browser, the page will be empty?
#RequestMapping(value = "/pics/{profileId}", method = RequestMethod.GET, headers = "Accept=application/json")
#ResponseBody
public List<ProfilePic> getProfilePics(#PathVariable("profileId") BigInteger profileId) {
return practiceServices.getProfilePics(profileId);
}
if visitor enters the url http://localhost:8080/practiceProject/pics/10, the page will show the list, but I don't want visitors to see it. I want the browser to show an empty page. Is it possible?
If you just want a quick solution check a header that will be sent within your AJAX requests. If this is not available just return null or whatever. You can also return a ResponseEntity<List<ProfilePic>> and in case the header is not present respond with a different HTTP status or just with an empty body or 204 (no content) using the ResponseEntity static methods / builder.
For example you can check if the header X-Requested-With is available with the value XMLHttpRequest. That is one of the default headers that will be sent when AJAX is used (but not always; I don't know exactly when it is sent and when not - maybe it depends on the used javascript library).
But keep in mind: This is nothing secure, someone can fake those headers and access the page anyway.
If you want such a behaviour for your complete API try it within a filter which checks this header and if available proceed with doFilter, otherwise stop and respond nothing.
You are returning the list on body of request, if you don't like to do it you should create a ModelAndView object and add the object list to it.
Example:
`#RequestMapping(value = "/pics/{profileId}", method = RequestMethod.GET, headers = "Accept=application/json")
public ModelAndView getProfilePics(#PathVariable("profileId") BigInteger profileId) {
ModelAndView view = new ModelAndView("html_to_be_returned");
view.addObject("list", practiceServices.getProfilePics(profileId));
return view
}'
PS: I have not test this code so it can have same issue.`

Attribute routing based on the existence of a querystring parameter

I would like two different methods to be called depending on whether the request is GET /things/123 or GET /things/123?preview
Obviously, this would be a workaround:
[RoputePrefix("api/things")]
...
[HttpGet, Route("{id}")]
public object GetThing(int id)
{
if (Request.RequestUri.Query == "?preview")
return GetPreview(id);
else
return GetFull(id);
}
...at which point it's almost like using bool preview = false as a parameter and adding ?preview=true to the request. But I want this syntax instead and would prefer to handle it with routing if possible.
For reasons not shown here, I can't do the next easiest thing, which is to use /preview as a suffix.

Ajax Web-Api optional parameter null issue.

Ajax webapi when parameter is null or blank then 400 bad reuqsest occurs. solution needed asap.
http://{parenturl}/api/BuildTypeWebApi/GetBuildTypeList?CurrPage=1&PageSize=10&BuildTypeName=
here BuildTypeName is optional parameter when there is not search parameter passed how to reduce 400 error.
//controller
public HttpResponseMessage GetBuildTypeList(int CurrPage, int PageSize, string BuildTypeName = "")
{
}
here issue with only BuildType.
help some one.
Regards
You need to change the way the request is made. Either complete your request string by adding ="" to the end, or leave out the BuildTypeName parameter when it is empty.
So you get either of these two cases:
/api/BuildTypeWebApi/GetBuildTypeList?CurrPage=1&PageSize=10&BuildTypeName=""
/api/BuildTypeWebApi/GetBuildTypeList?CurrPage=1&PageSize=10
This way, Web API actually knows what you want to do with the BuildTypeName parameter. In your case it was an incomplete request.

Testing Ajax Request in Cakephp 2.0

I have an action in my controller which does something only if the request is an XmlHttpRequest, like this:
function myAction() {
if( $this->request->is('ajax') ) {
doSomething();
}
}
What would a TestCase for this action look like? Is there a way to mock up the CakeRequest instance to appear as an Ajax request?
I don't know if it is a good way or not, but adding
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
at the top of the test method will do the job. In this case we send data as Ajax so not need to check any more.
we use a trick to solve ajax unit test for cake2.0
as cake supoprts .json extention, we create a function in AppModel to cheat ajax call. like
public function isAjax() {
return $this->request->isAjax() || $this->request->ext == 'json';
}
Then in controller, instead of calling $this->request->isAjax(), $this->isAjax() is used.
When testing action with ajax call, we simply add suffix .json to the action call, For example,
$this->testAction('/users/register');
This might not be the ultimate solution for ajax call test, but could be a workaround

Resources