AEM: Convert/Adapt resource to page - adobe

Resource object needs to be adapted to Page class or a way to extract/refer page related to resource. I have tried following way; however it does not seems to work
final Resource resource = resourceResolver.getResource(pagePath);
final Page cPage = resource.adaptTo(Page.class);
It returns null o cPage

Try with PageManager
With path:
https://developer.adobe.com/experience-manager/reference-materials/6-5/javadoc/com/day/cq/wcm/api/PageManager.html#getPage-java.lang.String-
With resource:
https://developer.adobe.com/experience-manager/reference-materials/6-5/javadoc/com/day/cq/wcm/api/PageManager.html#getContainingPage-org.apache.sling.api.resource.Resource-

Related

AEM Servlet not getting executed

I have a servlet with OSGI annotation like below
#Component( immediate = true, service = Servlet.class, property = { "sling.servlet.extensions=json",
"sling.servlet.paths=/example/search", "sling.servlet.methods=get" } )
public class SearchSevrlet
extends SlingSafeMethodsServlet {
#Override
protected void doGet( final SlingHttpServletRequest req, final SlingHttpServletResponse resp )
throws ServletException, IOException {
log.info("This is not getting called ");
}
}
But When i try to hit the servlet with JQuery
$.get( "/example/search.json", function( data ) {
$( ".result" ).html( data );
alert( "Load was performed." );
});
I am getting below information rather than servlet getting executed.
{"sling:resourceSuperType":"sling/bundle/resource","servletClass":"com.group.aem.example.servlet.SearchSevrlet","sling:resourceType":"/example/search.servlet","servletName":"com.group.aem.example.servlet.SearchSevrlet"}
Please let me know if i need to make any other configuration.
The info that you are getting is the answer of the Default JSON Servlet
Please read this: Servlets and Scripts
You are registering the "SearchServlet" with the property "sling.servlet.paths". This property is defined as:
sling.servlet.paths: A list of absolute paths under which the servlet is accessible as a Resource. The property value must either be a single String, an array of Strings...
That means that your servlet will be only triggered if you request the same exact path, in this case "/example/search", like this:
GET /example/search
I would recommend you to use the properties "resourceTypes" and "selectors" in your Servlet rather than "paths". For example, a better configuration could be:
property = {
"sling.servlet.resourceTypes=/example/search.servlet",
"sling.servlet.selectors=searchselector",
"sling.servlet.extensions=json",
"sling.servlet.methods=GET"
}
With this config, your SearchServlet should be triggered with a GET request to a resource with resourceType="/example/search.servlet", with the selector "searchselector" and the extension "json". For example:
GET /corcoran/search.searchselector.json
I had a similar problem with yours.
To find out what is wrong, I checked "Recent Requests" page.
(at http://localhost:4502/system/console/requests.)
In my case, there was a log saying, "Will not look for a servlet at (my request path) as it is not in the list of allowed paths".
So I moved to "Config Manager" page(at http://localhost:4502/system/console/configMgr), and searched for "Apache Sling Servlet/Script Resolver and Error Handler".
It has a list named "Execution Paths", and I added my request path to the list.
After adding my path to the list, the problem is solved.

Passing in a date to WebAPI - No HTTP resource was found that matches the request URI

I have a GET request that I make in Chrome Postman. It looks like the following:
http://localhost/WCAPI/Lookup/WCClassDesc/State/AL/Class/7230/DescCode/00/EffDate/2016-04-13
Can anybody see why I would get this response in Postman?
{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost/WCAPI/Lookup/WCClassDesc/State/AL/Class/7230/DescCode/00/EffDate/2016-04-13'.",
"MessageDetail": "No action was found on the controller 'WCClassDesc' that matches the request."
}
My code is:
using System;
using System.Web.Http;
/// <summary>
/// API for loading WCClassDescription which is shown on the PremByClass page.
namespace WCAPI.Controllers.Lookup {
[RoutePrefix("Lookup/WCClassDesc")]
public class WCClassDescController : ApiController {
[Route("State/{State}/Class/{Class}/DescCode/{DescCode}/EffDate/{EffDate}")]
public Models.Lookup.WCClassDesc Get(string ClassState, string ClassCode, string DescCode, DateTime EffDate) {
var desc = (new Premium.BLL.WCClassDesc()).GetCurrentWCClassDesc(ClassState, ClassCode, DescCode, EffDate);
var WC = AutoMapper.Mapper.Map<Models.Lookup.WCClassDesc>(desc);
return WC;
}
}
}
Any help or direction would be greatly appreciated.
Jason
There are multiple problems with your code, let's start from the URI:
Assuming you are testing your application using the root path of your host (localhost) and following your definition of RoutePrefix and Route attributes, the correct URI for your resource is the following:
http://localhost/Lookup/WCClassDesc/State/AL/Class/7230/DescCode/00/EffDate/2016-04-13
That's because there is no WCAPI defined in your RoutePrefix attribute.
The other problem is related to the route parameter mapping, you defined you parameters as {State} and {Class}, but then you are asking for ClassState and ClassCode inside your method.
Rename those parameters to match the ones defined in your route, or else Web API will not map them to your method parameters.

ASP.net MVC 5 Route with two parameter

I want create web application with 2 parameter. Add this Code to RegisterRoutes function:
routes.MapRoute(
"pageroute",
"page/{pageid}/{pagename}",
new { controller = "page", action = "Index", pageid = "", pagename = "" }
);
and add this method in pageController:
public ActionResult Index(int pageid,string pagename)
{
return View();
}
Now when i running application with this parameter
http://localhost:1196/page/4/Pagename
Application run successfully but when running with this parameter
http://localhost:1196/page/4/Pagename.html
Application return 404 error
HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
while add .html in parameter return 404 error. why?
Because by default HTML files are not being served through MVC/IIS.
Your application looks for a physical file named Pagename.html and cannot find it there. Hence - 404.
To make it work, you need to setup your IIS to catch requests for files with HTML extension and pass this request to MVC.
EDIT: Here is a similar question where OP found a solution by switching "Managed Pipeline Mode" to "Classic".
Try changing the Route to:
routes.MapRoute(
"pageroute",
"page/{pageid}/{*pagename}",
new { controller = "page", action = "Index", pageid = "", pagename = "" }
);
This will then match everything as in page/1/* so the .html should go via this route.
I was unable to reproduce an issue where a .html file gave a 404 using a scenario similar to the question, so there may be some other routing issue or IIS configuration causing this.

Strange behavior when using dynamic parameter in ASPNET WebApi and json request

I have really no good explanation what actually is happening and I hope someone here can explain this behavior.
First I go and create File=>NewProject=>Empty WebApi project.
Then I add one simple controller and host this on IIS.
[RoutePrefix("api")]
public class AccountController : ApiController
{
[HttpPost, Route("account")]
public async Task<IHttpActionResult> Post(dynamic command)
{
dynamic asd = command;
return Ok();
}
}
Then I hit the API with fiddler like this:
POST https://local.com/api/account HTTP/1.1
Content-Type: application/json
{"username":"user1","password":"secret","email":"email#domain.com"}
Then I put a breakpoint inside the controller and using the Immediate Window
command.email
'object' does not contain a definition for 'email' and no extension method 'email' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
BUT using the asd actually works. How is that? Any idea?
asd.email
{email#domain.com}
base: {email#domain.com}
HasValues: false
Type: String
Value: "email#domain.com"
Even more. If I change the dynamic to ExpandoObject I get the result bellow which I actually expect but through asd:
asd.email
"email#domain.com"

How to prevent static resources from being handled by front controller servlet which is mapped on /*

I have a servlet which acts as a front controller.
#WebServlet("/*")
However, this also handles CSS and image files. How can I prevent this?
You have 2 options:
Use a more specific URL pattern such as /app/* or *.do and then let all your page requests match this URL pattern. See also Design Patterns web based applications
The same as 1, but you want to hide the servlet mapping from the request URL; you should then put all static resources in a common folder such as /static or /resources and create a filter which checks if the request URL doesn't match it and then forward to the servlet. Here's an example which assumes that your controller servlet is a #WebServlet("/app/*") and that the filter is a #WebFilter("/*") and that all your static resources are in /resources folder.
HttpServletRequest req = (HttpServletRequest) request;
String path = req.getRequestURI().substring(req.getContextPath().length());
if (path.startsWith("/resources/")) {
chain.doFilter(request, response); // Goes to default servlet.
} else {
request.getRequestDispatcher("/app" + path).forward(request, response); // Goes to your controller.
}
See also How to access static resources when mapping a global front controller servlet on /*.
I know this is an old question and I guess #BalusC 's answer probably works fine. But I couldn't modify the URL for the JSF app am working on, so I simply just check for the path and return if it is to static resources:
String path = request.getRequestURI().substring(request.getContextPath().length());
if (path.contains("/resources/")) {
return;
}
This works fine for me.

Resources