I would like to call a Validator on some object, but not from within a Controller, and then get the Error object.
Could you provide a code sample for this?
Spring's docs show how to use Validator without a Controller in sight:
http://static.springsource.org/spring/docs/2.0.x/reference/validation.html
Been possible since the beginning. It's commonly used in Controllers and the web tier, but that's not required. There's no dependency on the web tier in the validator framework.
Related
There are a lot of definitions on what MVC is, but most of them say that the user contacts the controller and then the controller changes the view and sends it to the user. If I am using React.js for my frontend and calling endpoints in my controller, am I still using MVC pattern or not?
Is the #Controller even the same thing as the controller in MVC because in the definitions it says that the controller handles the application logic which in my case it does not I have service classes for that. I am writing an essay and I don't even know what type of application I am creating. It is driving me nuts.
Yep, it's still MVC. In this case you have controller (Spring #Controller or #RestController and React) model (services) and view (html generated by React). There is no strict definition what is MVC.
In MVC controller should not contain logic themself, but communicate with model (your services), this is the correct layered backend architecture. Otherwise, the Single Responsibility Principle is violated.
Spring Controller i.e., #Controller is the responsible person to provide the view the user requested if you need only the view page, it can be anything .html,.JSP and many more. So, if the user requested for any page either by the react.js or anything like angular then it calls the dispatcher servlet of the spring front controller and calls the handler mapper to which controller the user have requested.
If you requested something from the client to provide or do some crud operation then Rest Controller comes into the picture where #RestController...#Service...#Repository is been used.
So indirectly, the spring provides the way where developers can define the user request in the model view and controller format in which it segerrate the things separately and provides more convenient way to organise the code it looks like and spring have assigned annotations where it marks the class the responsibility it should behave.
How can we force developer to write Developed Custom-annotation on rest api
Example :
We Developed annotation Called : ValidatePermission
what we need to do , displaying runtime error for developer that he missing annotation #ValidatePermission on API , when he tried to write new api
#ValidatePermission
#GetMapping("/details")
#PreAuthorize("hasAuthority('902')")
public ResponseEntity<CustDtlsInqDto> getCustomerDetails(#CurrentUser UserPrincipal currentUser,
#RequestParam(name = "poiNumber", required = false) String poiNumber,
#RequestParam(name = "cif", required = false) String cif) {
return ResponseEntity.ok(customerService.getCustomerDetailsByPoiOrCif(currentUser.getId(), poiNumber, cif));
}
Annotations usage cannot be forced in any way before or on compilation (at least I am not aware of any technique, feel free to correct me).
The only way to go is to perform a check-up during the unit testing phase. Simply write an unit test that scans through the REST API definition beans and its public methods (or annotated) to check up using teh Reflection API whether an annotation from a particular category (implementation details up to you) is present within the formal parameters of methods.
Gits Github: Find all annotated classes in a package using Spring
Baeldung: A Guide to the Reflections Library
Something looks to me weird in this approach.
So you say:
...displaying runtime error for developer that he missing annotation #ValidatePermission on API
Based on this phrase, let me suggest an alternative:
So the developer that runs the project locally (during the debugging session or maybe tests) should see an error if he/she didn't put the annotation on the methods of rest controller, right?
If so, Why don't you need the developers to put this annotation?
The main idea of my suggestion is: Why not letting spring to do it for you automatically?
You could implement some kind of aspect or if you don't want to use a spring aop and prefer 'raw plain spring', BeanPostProcessor, that would 'wrap' all the methods of class annotated with RestContoller (by creating a run-time proxy) and before running a controller method will executed the logic that was supposed to be supported by the annotation?
In the case of Web MVC, another approach is to implement an interceptor that will be invoked automatically by spring mvc engine and you'll be able to execute any custom logic you want there, you'll also be able to inject other beans (like auxiliary services) into the interceptor.
Read this article in case you're not familiar with these interceptors, you'll need preHandle methods as far as I understand.
I have an external IAM service (provides authentication and authorization features) which I would like to use to authenticate user requests.
I will ignore the code in below examples as it is not relevant.
In my IAMServiceImpl I have the authenticate(String token) method, which will validate the token.
I would like to reuse this method in all the controller methods, but I would like to avoid injecting the IAMServiceImpl in all the controllers.
Question: How can I register this method to be called at the beginning of each controller method, without injecting the service in all the controllers.
NOTE I have to pass the token to the service, which I will get from request headers.
Thank you!
You should use Aspect Oriented Programming, it is good solution for your use case.
Have a look at Spring's documentation for AOP, specifically #Before advice.
https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#aop
There are two ways (might be more):
1) Spring AOP: You can setup an advice to be executed before controller gets called in.
2) Filter chain (more suitable for your use-case): Spring security has a set of filters that can be used to provide authentication and authorization.
Maybe you could use Shiro or Spring Security to help you achieve these like filters, or you could use Aspect Oriented Programming before each Controller.
I'm trying to clear my concept about Interceptors in Java EE. I have read Java EE specification but I'm little confused about it. Please provide me some useful link or tutorial which could clear my concept. How, When, Why do we use interceptors?
Interceptors are used to implement cross-cutting concerns, such as logging, auditing, and security, from the business logic.
In Java EE 5, Interceptors were allowed only on EJBs. In Java EE 6, Interceptors became a new specification of its own, abstracted at a higher level so that it can be more generically applied to a broader set of specifications in the platform.
They intercept invocations and life-cycle events on an associated target class. Basically, an interceptor is a class whose methods are invoked when business methods on a target class are invoked, life-cycle events such as methods that create/destroy the bean occur, or an EJB timeout method occurs. The CDI specification defines a type-safe mechanism for associating interceptors to beans using interceptor bindings.
Look for a working code sample at:
https://github.com/arun-gupta/javaee7-samples/tree/master/cdi/interceptors
Java EE 7 also introduced a new #Transactional annotation in Java Transaction API. This allows you to have container-managed transactions outside an EJB. This annotation is defined as an interceptor binding and implemented by the Java EE runtime. A working sample of #Transactional is at:
https://github.com/arun-gupta/javaee7-samples/tree/master/jta/transaction-scope
Interceptors are used to add AOP capability to managed beans.
We can attach Interceptor to our class using #Interceptor annotation.
Whenever a method in our class is called, the attached Interceptor will intercept that method invocation and execute its interceptor method.
This can be achieved using #AroundInvoke annotation ( see example below ).
We can intercept life cycle events of a class ( object creation,destroy etc) using #AroundConstruct annotation.
Main difference between Interceptor and Servlet Filters is We can use Interceptor outside WebContext, but Filters are specific to Web applications.
Common uses of interceptors are logging, auditing, and profiling.
For more detailed introduction, you can read this article.
https://abhirockzz.wordpress.com/2015/01/03/java-ee-interceptors/
I like this definition: Interceptors are components that intercept calls to EJB methods. They can be used for auditing and logging as and when EJBs are accessed.
In another situation, they can be used in a situation where we need to check whether a client has the authority or clearance to execute a transaction on a particular object in the database. Well, this is where Interceptors come in handy; they can check whether the client/user has that authority by checking whether he/she can invoke that method on that database object or EJB.
However, I would still have a look at the following article and the following tutorial to get an idea of how they are used in a Java EE setting/environment.
You can use Interceptor for the places where you want to perform some tasks before sending a request to the Controller class and before sending a request to a responce.
Ex:- Think you want to validate the auth token before sending a request to the Controller class in this case, you can use Intercepters.
Sample code:
#Component
public class AuthInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse
response, Object handler) throws Exception {
//Here you can write code to validate the auth token.
}
}
Let's say that I have a #Controller with two methods that do related but different things. I want to expose them on the same URL endpoint but have different functionality depending on the security context. Now I know that I could have a single mapped request method and dispatch to different utility functions within my class, but could I wire it so that Spring MVC will handle the dispatch for me based on what comes in?
As a strawman example, there's code that dispatches between ROLE_ADMIN and ROLE_USER, but my actual use case is a good chunk more complicated:
#Controller
public class Controller {
#RequestMapping("/api/thing")
#PreAuthorize("hasRole('ROLE_ADMIN')")
public String doAnAdministrativeThing() {
... (admin-priviledge stuff goes here)
}
#RequestMapping("/api/thing")
#PreAuthorize("hasRole('ROLE_USER')")
public String doADifferentThing() {
... (normal-priviledged stuff goes here)
}
}
To preempt any rabbit holes:
No, I might not have any choice about having the two functions be on different URLs or having different parameters or any of the "normal" #RequestMapping bits
The security context differences are complex but can be processed within a #PreAuthorize expression
There are actually more than two different contexts to dispatch on
I think that this will not work, global method security has absolutely nothing to do with MVC layer.
Moreover it's officially recommended to use method security only for the service layer
Generally we would recommend applying method security at the service
layer rather than on individual web controllers.
P.S. generally I try to avoid using AOP with Spring controllers, and declare AOP methods only in the root context(and not in the servlet context), because proxying controller instance can lead to some confusing behavior, and forces the users to know Spring AOP specific things, like difference between JDK proxy and CGLIB proxy, how annotations are processed, etc.
This will work with some extensions. See the reference to GitHub mohchi / spring-security-request-mapping in #andy's answer to Can Spring Security use #PreAuthorize on Spring controllers methods?