How may I secure single eventhandlers by annotations?
I know how to secure Complete pages, but i have no idea how to check before invocation if a a method has an annotation.
Is this possible?
I dont want to use Spring-security
Thanks
ChenillKit access is a nice module.
There is also the tapestry-security module based on the security framework Apache Shiro which provides annotation like
#RequiresPermissions("news:delete")
public void onActionFromDeleteNews(EventContext eventContext) {
...
}
With the Chenillekit access module you can use the #Restricted annotation on an Event method as well like so:
#Restricted(role = YOUR_ROLE_CONSTANT)
#OnEvent(value="eventName")
private Object handleEvent() throws Exception {
... your event code ....
}
Related
I'm trying to use Spring AOP to add logging to methods coming from a third party library. So there is a class, ProxyServlet, that is being used by my Spring Boot application, and I just want to apply logging to it.
#Pointcut("within(com.common.httpproxy.ProxyServlet)")
private void proxyServlet() {}
#Before("proxyServlet()")
public void testLog() {
log.info("THIS IS WORKING");
}
This is just some test AOP code right here. I know that my Spring AOP is set up, because I can get log output for any classes included in my codebase. However, I can't get log output for any classes from a third party library, like the ProxyServlet.
Is there anything I can do to get this AOP advice to work?
You should annotate the class containing this code with:
#Aspect
#Component
Assuming that the ProxyServer instance is a bean, you can achieve it by defining an aspect for the logging something like below.
#Aspect
public class LoggingAspect {
#Before(execution(* the.package.ProxyServlet.*(..)))
public void loggingAdvice(JoinPoint joinPoint){
System.out.println("Started loggingAdvice on method="+joinPoint.toString());
System.out.println("The aruguments are =" + Arrays.toString(joinPoint.getArgs()));
}
}
Please note that it is not necessary to have a custom point-cut like #LoggingAdvice here and annotate the target method using it (I am pointing it because you mentioned that the class is in third party library by which means you are expressing the concern that you may not be able to annotate meothod(s) with a pointcut) . Custom point-cuts are useful when you define widely applicable Aspects and limit the application of it to certain joint pints (thru the custom pointcut)
As your target is a single class and is third party library, you are good without a custom point-cut but with an aspect specifically targeting the required class.
The above define Aspect will be executed for every method defined in the ProxyBean class.
To use jamon in spring, it's described to use JamonPerformanceMonitorInterceptor and put it to springs AOP-mechanism via a applicationContext.xml. It's explained, and there's an example within the tests in it's sources. Unfortunately, I want to build a spring-boot application without any xml-configuration.
Is it possible to use some annotations to include the JamonPerformanceMonitorInterceptor to spring?
Better late than never...
I had the very same situation: I needed to configure JAMon without any XML configuration. Most of the examples online (including the comments in the JAMon source code) advertise XML configuration flexibility, but I couldn't find any examples with annotation based configuration. Also annotation-based configs are not necessarily less flexible, they just need to be conceptually separated and not confused with functional parts of the application. I think such advisor can be a good example:
#Component
public class MonitoringAdvisor extends AbstractPointcutAdvisor {
private final StaticMethodMatcherPointcut pointcut = new StaticMethodMatcherPointcut() {
#Override
public boolean matches(Method method, Class<?> targetClass) {
return targetClass.isAnnotationPresent(RestController.class);
}
};
#Override
public Pointcut getPointcut() {
return this.pointcut;
}
#Override
public Advice getAdvice() {
return new JamonPerformanceMonitorInterceptor(true, true);
}
}
This advisor would let Spring/AOP know to run JAMon monitoring advice on any method of Spring bean annotated with #RestContrller. This advisor should be configured/added to the same Spring context as rest controllers.
Note, that in my case I specifically wanted to monitor my rest controllers. One can adapt the advisor according to his/her own needs. (In my code I use a more advanced/configurable version of the presented advisor)
Is this Spring Boot sample application helpful?
Here is the relevant part of the Spring AOP manual.
I'm using Tomcat 6.0.33 with Java 6. I have this servlet ...
public class SaveXmlServlet extends HttpServlet {
private CacheService cacheService;
public void init(ServletConfig config) throws ServletException {
cacheService = CacheServiceLocator.cacheService();
} // init
How can I redesign my servlet to ...
Take advantage of dependency injection so that a mocking framework like mockito can inject its own "cacheService" implementation
Guarantee that there is only one instance of cacheservice in my jvm. Right now the line "CacheServiceLocator.cacheService()" guarantees this.
? I'm not using (or allowed to use) frameworks like Spring or Guice. Grateful for any thoughts on refactoring this. Thanks, - Dave
There are a few options, although I recommend smacking someone for not "letting" you use a framework. Two quickies; I'm sure there are others. I'd go the smacking route first.
You can mock static classes using a combination of EasyMock/Mockito and, say, PowerMock. Technically you don't need to change anything at all to get the in-test behavior you want.
A class name provided by a servlet init parameter or JNDI resource could be used to create an instance of the cache locator. Providing a setter for the same allows a unit/etc. test to set it on the class.
Is JSR-303 also intended for method parameter validation?
If so, is there any example on the web? The biggest challenge I'm facing is how to get a validator within each method. With Spring 3, doesn't it mean that I'd have to inject virtually every class with a LocalValidatorFactoryBean?
Thanks!
Method level validation will be supported in the upcoming version 4.2 of JSR 303's reference implementation Hibernate Validator.
As pointed out in the previous answer this will allow constraint annotations (built-in as well as custom defined types) to be specified at method parameters and return values to specify pre- and post-conditions for a method's invocation.
Note that HV will only deal with the actual validation of method calls not with triggering such a validation. Validation invocation could be done using AOP or other method interception facilities such as JDK's dynamic proxies.
The JIRA issue for this is HV-347 [1], so you might want to add yourself as watcher to this issue.
[1] http://opensource.atlassian.com/projects/hibernate/browse/HV-347
The javadocs for each of the JSR 303 annotations tells the following:
#Target(value={METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER})
See, PARAMETER is there. So, yes, it's technically possible.
Here's an example:
public void method(#NotNull String parameter) {
// ...
}
I'm however not sure how that integrates with Spring since I don't use it. You could just give it a try.
In Spring 3.1.0 you can use #Validated annotation to activate validation on a pojo.
Create an interface for the pojo class an put this annotation over it, then add your validation annotations in the methods definitions. ( the interface is required because Spring will create a proxy class using the interface as definition )
#Validated
public interface PojoClass {
public #NotNull String doSomething(#NotEmpty String input);
}
your pojo :
public class PojoClassImpl implements PojoClass {
public String doSomething(String input) {
return "";
}
}
Starting from a standard spring web application with active validation, remember to add in your spring configuration this bean declaration:
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
This sounds like a use case for AOP (AspectJ). Write a pointcut for methods that are annotated with javax.validation.constraints.*, inject a validator into the aspect (probably using Spring) and use a #Before or #Around advice to perform the validation before method execution.
Read AspectJ in Action for reference.
You can use jcabi-aspects (I'm a developer), which integrates JSR 303 with AspectJ. Actual validation is done by one of JSR 303 implementations, which you will have to add to class path, like Hibernate Validator, or Apache BVal.
I have a bunch of java custom tags that use spring managed beans.. since i cant find a way to inject into a custom tag, i created a helper class that provides static methods to "getTheObjectINeedBean()" for all the spring bean objects i need.. I do not like this approach at all.
i really want to be able to inject a spring managed bean into the custom tag
Is there a way? As far as my research goes, I understand there is no way to do this, because the custom tag is container managed
Thanks,
Billy
You are correct there isn't a simple way to use dependency-injection in jstl tags, because they are not managed by spring, and cannot be. However there are (at least) two workarounds:
#Configurable - aspectJ allows you to plug a weaver at load-time/compile-time, so that even objects that are not instantiated by spring can be spring aware. See here
You can create a base tag class for your project, and call an init(..) method from every doStartTag(..) method. There, you can get the ServletContext from the pageContext, and thus obtain the spring ApplicationContext (via ApplicationContextUtils). Then:
AutowireCapableBeanFactory factory = appCtx.getAutowireCapableBeanFactory();
factory.autowireBean(this);
Neither options are perfect as they require either some additional code, or some "black magic"
To expand on #Bozho's post, I have gotten this to work like so: (in spring 3.0 there is no ApplicationContextUtils that I could find)
public class LocationTag extends RequestContextAwareTag {
#Autowired
PathComponent path;
...
#Override
protected int doStartTagInternal() throws Exception {
if (path == null) {
log.debug("Autowiring the bean");
WebApplicationContext wac = getRequestContext().getWebApplicationContext();
AutowireCapableBeanFactory acbf = wac.getAutowireCapableBeanFactory();
acbf.autowireBean(this);
}
return SKIP_BODY;
}
}
The solution as described above works but some background and additional code snippets are, quite likely, useful.
1) The doStartTagInternal method is invoked from the doStartTag method.
2) I was forced to set the pageContext first before invoking the doStartTag
3) I did a lookup of the bean as opposed to the autowiring. To me this seems more straightforward: (YourBeanProxy) autowireCapableBeanFactory.getBean("yourBeanName")
Hopefully this additional info is useful.