How does playframework distribute request action, reflection? - java

I've used both Play1.x and Play2.x, but I didn't find how Play distributes its request to different actions in its source code.
e.g.
http://HOST:9000/Application/index
Play could find the controller Application, and then invoke its index method.
I thought Play works this way:
Get URI's first part Application and init Application using reflection.
Get the second part of URI, index, invoke index() of Application using reflection.
But I don't know where's the code exactly.
And, If it using a lot of reflection, how could it handle millions of request ? I think reflection is a lot of slower than direct method call(Or Play make some magic optimize ?).

Route file get compiled into target/scala-2.10/src_managed/main/routes_routing.scala file.
Even if reflection would be involved why should it be slow? File need to be reflected once at app startup.

The route file points each uri to a specific method.
For example:
GET /clients/:id controllers.Clients.show(id: Long)

If you don't care about routes type-safety incorporated in Play 2.x you can easily write custom resolver which will catch all unhandled routes with Dynamic parts spanning several / so using simple string operations + reflections you can access any controller/action combination you want...
Anyway consider if your app's security is worth of this sacrifice.
PS.: hard believing that samples are not required to this approach, in other case let me know, I'll write something in free time

Related

Configuring Java contextPath to accept dynamic value

I am trying to configure a context path for an API in a way that best leverages the features of Spring Data Rest. The way the API is designed ensures a client can only ever see the records belonging to them and no other clients. As such, the base URL is similar to "/root/employer/{employerId}".
I am trying to set the context path in the main class with System.setProperty("server.servlet.context-path", "/root/employer/{employerId}"). Based on my limited understanding, however, since the context path is a String, this is being rendered in Postman as "/root/employer/%7BemployerId%7D" as opposed to the desired format, and is therefore not recognizing actual IDs when they are passed in.
Is there a known way to resolve this? Alternatively, is there a better approach to this dilemma altogether?

Details on how front end interacts with back end?

Consider this line of jsp code:
function clearCart(){
cartForm.action="cart_clear?method=clear";
cartForm.submit();
}
Clearly it's trying to call a method on the back end to clear the cart. My question is how does the service (Tomcat most likely, correct me if I'm wrong) which hosts this site that contains this snippet of code know how and where to find this method, how it "indexes" it with string values etc. In my java file, the clear method is defined as:
public String clear( )
{
this.request = ServletActionContext.getRequest();
this.session = this.request.getSession();
logger.info("Cart is clearing...");
Cart cart = ( Cart ) this.session.getAttribute(Constants.SESSION_CART );
cart.clear();
for( Long id : cart.getCartItems().keySet() )
{
Item it = cart.getCartItems().get(id);
System.out.println( it.getProduct().getName() + " " + it.getNumber()
);
}
return "cart";
}
By which module/what mechanism does Tomcat know how to locate precisely that method? By copycatting online tutorials and textbooks I know how to write these codes, but I want to get a bit closer to the bottom of it all, or at least something very basic.
Here's my educated (or not so much) guess: Since I'm basing my entire project on struts, hibernate and spring, I've inadvertently/invariably configured the build path and dependencies in such ways that when I hit the "compile" button, all the "associating" and "navigating" are done by these framework, in other words, as long as I correctly configured the project and got spring etc. "involved" (sorry I can't think of that technical jargon that's on the tip of my tongue), and as long as I inherit a class or implement an interface, when compiling, the compiler will expose these java methods to the jsp script - it's part the work done by compiler, part the work done by the people who composed spring framework. Or, using a really bad analogy, consider a C++ project whereby you use a 3rd party library which came in compiled binary form, all you have to do is to do the right inclusion (.h/.hpp file) and call the right function and you'll get the function during run time when calling those functions - note that this really is a really bad analogy.
Is that how it is done or am I overthinking it? For example it's all handled by Tomcat?
Sorry for all the verbosity. Things get lengthy when you need to express slightly more complicated and nuanced ideas. Also - please go deep and go low-level don't go too deep, by that I mean you are free to lecture on how hibernate and spring etc. work, how its code is being run on a server, but try not to touch the java virtue machine, byte code and C++ pointers etc. unless of course, it is helpful.
Thanks in advance!
Tomcat doesn't do much except obey the Servlet specification. Spring tells Tomcat that all requests to http://myserver.com/ should be directed to Spring's DispatcherServlet, which is the main entry point.
Then it's up to Spring to further direct those requests to the code that handles them. There are different strategies for mapping a specific URL to the code that handles the request, but it's not set in stone and you could easily create your own strategy that would allow you to use whatever kind of URLs you want. For a simple (and stupid) example you could have http://myserver.com/1 that would execute the first method in a single massive handler class, http://myserver.com/2 would execute the second, etc.
The example is with Spring, but it's the same general idea with other frameworks. You have a mapper that maps an URL to the handler code.
These days it's all hidden under layers of abstraction so you don't have to care about the specifics of the mapping and can develop quickly and concentrate on the business code.

Java REST is there a way to default to a particular method if none of the paths match? (Instead of getting a 405)

I apologize if some of my terminology is off, I'm still trying to learn:
I'm using the Dropwizard framework and I have a resource class with all my various POST/GET/etc methods. They all work fine when hit from Postman, browsers, etc. If I try something that has no matching path in the resource class I get an exception with HTTP status 405 - method not allowed.
Is there a way to default to some other method where I can display troubleshooting help -- like a list of what the available APIs are or a link to some documentation? Sort of like a try catch type of logic. Not sure what the options are or if there is a best way to do this.
Any help is appreciated. Thanks!
I don't think you might want to do that. REST over HTTP is driven "mostly" by the HTTP method and the end-point the same will act upon it.
In any stack, try to avoid that since you have specific actions for specific resources...anything else should be treated as something the server didn't understand, in the same way the HTTP protocol would behave.
Being said that, just apply a wildcard, usually * to one of the methods as a fallback action. That should work on Jersey and Spring Boot (MVC) as well.

Java annoations

I used a lot annotations in java but I never wrote one. I read though several guides and I am really confused.
They are using annotations like meta information eg names, age etc. That is really confusing because I want to do something different
http://www.developer.com/java/other/article.php/3556176/An-Introduction-to-Java-Annotations.htm
I want to control the function calls.
for example
#Permission(user)
public static void account(){
...
}
So my functions only gets called if the user has the permission, otherwise the user should be redirected to the login page.
I could not find any information, maybe I am using the wrong keyword?
I hope you can clear things up,
Thanks.
You can do that, but with a lot of extra code. Intercepting method calls is part of AOP (aspect oriented programming). You need to make proxies of you target objects, and in the invocation handler parse the annotation.
Luckily, you don't have to do that - since you have a webapp, just use spring/spring-mvc/spring-security. Spring gives you an AOP framework that you can use to define aspects handling your permission logic
Not sure how you can do this by yourself but if you are using Spring they have something that may help
http://static.springsource.org/spring-security/site/docs/3.0.7.RELEASE/reference/el-access.html
I use it my current project and it works well
Something like that should really be done in the function itself (or in some other part of the program). Note that annotations provide data about a program that is not part of the program itself (see this reference).
I think what you are after is an AOP advisor which is run before your method. See here: http://java-questions.com/spring_aop.html
As an alternative to Spring, you could use AspectJ: http://www.andrewewhite.net/wordpress/2010/03/17/aspectj-annotation-tutorial/

writing Operation logs using the Servlet Filters

We want to write operation logs in our application for all the operation being made to DataBase. The operation log should contain the operation info(the data being "add/modify/delete") and the result of the operation(success/failure).
Since there are more number of action classees, adding the code to write operation log in each action class looks difficult. So I thought of writing this part of code in the Servlet Filter.
But I have a problem here, I need to know the operation status(success/failure) but this is not possible in the filter with out parsing the response object. But parsing the response object looks difficult.
Can you suggest any alternative way to do this?
Thanks,
Chandra
If your application is AOP-based like Spring, then you can define aspects which can check for criteria like classes of a particular package, methods of a particular type (get/set/both). Using these aspects you can add logging.
I think the best way to achieve this is to add some extra logging to the JDBC driver. In the past I used Log4JDBC project.

Categories

Resources