Java Web Architecture - rest

I am interested in putting together a URL Auction research site. It will be structured as a standard [Presentation Layer <-->Business Layer <--->Data Layer]. This site will have an index.html that will allow users to enter a url they are interested in. That index.html will then call a doPost method via servlet which in turn spits out a results page of whether or not that URL is for sale like so:
index.html
<html>
<head>
<title>URL Auction Search Page</title>
</head>
<body>
<CENTER>
<FORM ACTION="/ResultServlet/Results" METHOD=GET>
<INPUT TYPE=TEXT NAME="st">
<INPUT TYPE=SUBMIT VALUE=Submit>
</FORM>
</CENTER>
</body>
</html>
Servlet:
#WebServlet("/Results")
public class Results extends HttpServlet {
private static final long serialVersionUID = 1L;
public static String str="";
private String businessLogic(String q){
try {
str = new compute.URL.GetAvailURI( "https://www.registerdomains.com/auctionAPI/Key:a05u3***1F2r6Z&urlSearch="+q);
/*more boring number crunching */
return str;
}
/*
protected void doGet(HttpServletRequest request, HttpServletResponse response)
}
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Results r = new Results();
String st = request.getParameter("st");
response.sendRedirect("results/resultActionURL.html?st="+r.businessLogic(st)");
}
}
However, there will be 2 other links from the results page that I need to process. Namely, a link called WhoOwnsThis.html which takes whois data and geographically maps this information on Google maps. Also, AppraiseResult.html that gives a real time appraisal of the url in question. OK- these 2 pages will take time (very loosely we’ll say 2 sec. ea.) to crunch so I am presenting the user with the results page while I then go on in the background and create the data for each of the other two results pages.
Question-
How do I handle the statefulness of these three results pages? My first thought is to create a unique directory each time the two additional results pages are created(WhoOwnsThis and AppraiseResult). Then I can embed the unique dir name as an argument in the results page url so that when they click on the link to the other 2 results pages, the dir name will be pulled from the results page url as a .js var and inserted to get the right page. However, I am also reading up on REST and wondering if that is a better way of handling the state for this transaction. What would industry standard recommend in this scenario?

Do you really want to work with such a low level API as Servlets? If you are open-minded look at Play Framework 2.0 and get the same experience as everyone on other platforms enjoy. If not, Spring MVC is a good choice. And if you prefer to just have JavaScript frontend then JAX-RS is a good choice.
Note that Play Framework 2.0 includes it's own class reloading mechanism, but you get the same experience with JRebel in other frameworks as well.
State in general is good to keep in the database, so it will be easy to scale. Java EE 6 Web Profile also gives you stateful session beans. Spring MVC has session scoped beans. Each of them do it in their own way, but as it is such a basic concept, there is plenty of documentation on their site and I'm not going to paste it here.
Have fun and welcome to the era of simple Java :)

I think the more modern layering is four-tiered:
View->Controller->Service->Persistence.
You can choose between asking the Java EE app server to maintain state for you either in the web tier via sessions or as stateful services in the service layer.

Related

Running both aspx and .Net Core (.Net 5) webpages on same server and domain

I am about to move a webshop from old webforms to new .Net Core (.Net 5) site.
The old urls have a lot of good rating on google and I would like to be able to make a permanent redirect from an aspx page to .net core page.
Etc.:
www.mydomain.com/products/great-backpack-1234.aspx
to
www.mydomain.com/great-backpack
I believe that requires that I have both .net core and aspx site running on the same domain.
Is this possible?
Or do any one have any other solution ideas?
Best regards
Thats probably not needed to run both on the same domain or space. It seems everything will end in .aspx, and assuming you are using MVC, a controller function to catch-all requests that don't match other routes, then check to see if it ends in aspx, should do it for you. You can put it in an existing controller, but I personally would put it in a new one to separate concerns
public class RedirectController : Controller
{
[Route("{**url}", Order = 999)]
public IActionResult RedirectPage(string url)
{
//Redirect logic based on the URL given, making sure it ends in aspx
}
}
The url would come across in the url parameter as a string and you can check to see if it ends in aspx, and what the page name was to determine where to send them. So "www.mydomain.com/products/great-backpack-1234.aspx" would come across in the url parameter as "products/great-backpack-1234.aspx". Note that the order field in the route attribute assures that it will be the last match checked for patterns, so it shouldn't mess with anything else.

AEM 6.x: How do I temporarily/programmatically disable the link checker? (trying to return a JSON with links back to browser)

So I have a Sling servlet that reads data from another API (let's call it APIX) and APIX gives me the data in JSON format.
When I debugged my code, it seems the response I get from APIX is intact.
When I pass the JSON I got from APIX to browser, I can see that AEM has "link checked" all the links I have in the JSON. I don't want AEM to do anything with my data.
Base on this Adobe page, I added these lines in my code:
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
LinkCheckerSettings linkCheckerSettings = LinkCheckerSettings.fromRequest(request);
linkCheckerSettings.setIgnoreExternals(true);
//body of the code here
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
printWriter.write(jsonResponse);
linkCheckerSettings.setIgnoreExternals(false);
}
No effect. I can still see these string
<img src="/libs/cq/linkchecker/resources/linkcheck_o.gif" alt="invalid link: _blank\\" title="invalid link: _blank\\" border="0">
everywhere.
I then tried disabling Linkchecker (via configMgr/Day CQ Link Checker Transformer) and still no effect.
How can I do it?
I called the Slng servlet by typing this URL in my browser: http://localhost:4502/servlets/getpublications?name=john.smith
Thanks!
EDIT:
This is a sample of the JSON data I'm getting from APIX (debugging on IntelliJ):
"LINKS":[
"<a x-cq-linkchecker=\"skip\" target=\"_blank\" href=\"http:\/\/www.google23.com\">[Web Link]<\/a>"
]
This is what I'm getting on the browser (the a tag was somehow replaced by an img tag)
"LINKS":[
"<img src="/libs/cq/linkchecker/resources/linkcheck_o.gif" alt="invalid link: _blank\\" title="invalid link:_blank\\" border="0"> [Web Link]<\/a>"
]
I have tried using valid and skip for x-cq-linkchecker but nothing happens.
Day CQ Link Checker Transformer config screenshot
I don't think disabling LinkChecker at a global level is recommended. There are a few more ways you can achieve this and place the restriction to only certain use cases -
If the link contains special prefixes like tel:, mailto: etc, - you'll have to add them to Day CQ Link Checker Service in /system/console/configMgr to disable LinkChecker for these links.
Add this parameter x-cq-linkchecker="valid" to the <img> tag to ensure links are marked as valid in AEM - even though AEM considers them invalid.
You can also use x-cq-linkchecker="skip" to skip link checker validation for this element.
You might encounter caching issues after updating the above params(2. and 3.), just try deleting contents in /var/linkchecker before you start testing.
There are multiple techniques for handling special url patterns, Refer here. And a very good link checker guide here.
Technique 1: Code way(Not recommended since not maintainable). Add class x-cq-linkchecker=”skip”
Technique 2: Disable link checker. Definitely not recommended in author. Author should witness broken links visible. However it is recommended to disable in publish rather than showing ugly broken link icon.
Technique 3: Add special url pattern. Your link checker should looks like this:

Spring MVC authorization in REST resources

I have REST api for accessing "parties" and the URL's look like this:
/parties
/parties/{partyId}
Using Spring controllers and #PathVariable I'm able to implement this interface. But to prevent users from accessing parties they don't have access to, I have to add checks to every method call which is kind of repeating myself and I might forget to add it everywhere:
#RequestMapping(value="/parties/{partyId}", method=RequestMethod.GET)
public #ResponseBody Party getParty(#PathVariable Integer partyId){
authorizeForParty(partyId);
...
Now what I would like to do is create a check that would be called every time that user enters url like this:
/parties/{partyId}/**
How would I do something like this? Do I have to create some servlet filter and parse the url myself? If I have to parse the url then is there atleast tools that would make it easy? I wish there was a way to add a method to controller that would be called before methods but could still use #PathVariables and such...
What I ended up with is using the Spring MVC interceptors and parsing the path variables in the same way that Spring does. So I define an interceptor for the REST url:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/parties/*/**" />
<bean class="PartyAuthorizationInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
The PartyAuthorizationInterceptor has to implement HandlerInterceptor in which we have to implement preHandle. It has HttpServletRequest as a parameter so we can get the request URL but we still have to parse the partyId from the url. After reading how Spring MVC does it, I found out they have a class named org.springframework.util.AntPathMatcher. It can read the path variables from the URL and place the values in a map. The method is called extractUriTemplateVariables.
So the result looks like this:
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String partyIdStr = new AntPathMatcher().extractUriTemplateVariables("/parties/{partyId}/**", request.getPathInfo()).get("partyId");
...
That makes the parsing almost as easy as using #PathVariable in MVC Controller methods. You still have to do conversions yourself(e.g. String -> Integer).
Now I can implement authorization logic on all urls that access a party in this interceptor and keep that logic out of the individual controller methods. Not as easy as I would have hoped but it gets the job done.
Are you already using some kind of security library in your application, e. g. Spring Security?
Because the kind of logic you want to implement is a classic case for an AccessDecisionVoter in an authentication chain. You would just put your API behind Spring Security's protection and implement the custom check as part of the security chain.
If you are not using a security framework at all, your idea of implementing a HandlerInterceptor may be the best alternative, though. But it would require you (as you mentioned) to take into account all kinds of obfuscation the user may use in order to gain access to other URLs (e. g. %-encoding of letters, ../../ patterns etc.).

Use RESTful URLs in a non-MVC site

I started the site using AST.NET Razor template, not ASP.NET MVC template.
I recall seeing somewhere on the Internet that even without MVC, it's possible to use RESTFul URLs in the razor-based ASP.NET site. It appears to work without the CHTML extension names right out of the box -- www.test.com/car automatically redirects to www.test.com/car.cshtml.
But, what if I used www.test.com/car/2, how would I get to the "2" inside the View without using MVC? I really hope that's something already baked in.
Found it -- it's in UrlData
http://beta.asp.net/web-pages/tutorials/aspnet-razor-pages/18-customizing-site-wide-behavior
section "How Routing Works"
Look at the WebGet Attribute. It has a UriTemplate.
Example:
WebGet(UriTempate="{Id}")<br>
public JsonResult Get(int Id)
{
}

How to stay in same page when executing a Server request in a portlet

I am calling a webpage from a portlet. The webpage is a form for user to enter data and has a button which submits the user data into Database.
But the Button also redirects the portlet site to the webpage through the proxy Gateway.
How to stay in the same portlet page while having the Form data submitted to the database?
You could use AJAX
Just adding to the AJAX answer..
A standard JSR 286 portlet supports such asynchronous action through serveResource method in the portlet class, which you'll need to override.
In the java file,
public void serveResource(ResourceRequest request, ResourceResponse response)
throws PortletException, IOException {
//Write or invoke your database code here...
}
Also, in the html <form> tag you will need to set <portlet:resourceURL> in the action attribute.
Hope this helps, even though I am assuming by portlet you mean Java portlets and not something else