I have a simple and maybe stupid question so apologies in advance..
I have been reading some spring-boot java code recently I am able to understand almost all for I have been able to find documentation everywhere.. but for example for this I still can't figure out the exact meaning (I am not able to find the annotation #P):
public MyFileEvent getEvent(
#P("user") User user,
#P("file") #Valid #RequestBody EventFile file) throws MyException {
return myService.getFileEvent(file);
}
I understand #Valid and #RequestBody but I don't find the meaning of #P.
According to the javadoc:
"An annotation that can be used along with AnnotationParameterNameDiscoverer to specify parameter names. This is useful for interfaces prior to JDK 8 which cannot contain the parameter names."
There are in fact two versions of the #P annotation:
org.springframework.security.access.method.P since Spring 3.2 (deprecated)
org.springframework.security.core.parameters.P since Spring 5.0
Related
I am reviewing open source spring projects. I am confused about the use of annotations around here. I want to ask to clarify this.
#Target(ElementType.METHOD)
#Retention(RUNTIME)
#Bean
public #interface Merge {
#AliasFor("targetRef")
String value() default "";
#AliasFor("value")
String targetRef() default "";
Placement placement() default Placement.APPEND;
int position() default 0;
Class<MergeBeanStatusProvider> statusProvider() default MergeBeanStatusProvider.class;
boolean early() default false;
}
An annotation has been created here named Merge. It has different parameters and default values.
#Configuration
public class LocalConfiguration {
#Merge(targetRef = "mergedList", early = true)
public List<String> blLocalMerge() {
return Arrays.asList("local-config1", "local-config2");
}
}
And this is usage of #Merge annotation in any class I choosed randomly.
When I examined the code, I could not find any class related to the implementation of Merge annotation. By the way, this problem I'm having isn't just about this annotation. Almost all the annotations I have examined are used without being implemented in any way.
I think I will understand the others if we start from this annotation.
What does this anotation do? What kind of message does it give to the place where it is used. How does the application understand what that annotation does in runtime without being implemented anywhere.
Thanks.
Annotations don't have implementations. They are processed by external classes or tools depending on the RetentionPolicy. In this case, the Merge annotation has Runtime retention so it will be available via reflection once the class is loaded. At runtime any interested party (in this case I assume the Spring Framework) can use getAnnotations on your LocalConfiguration class to detect the Merge annotation and take whatever action that needs to be taken. The possibilities are really up to the framework that defined the annotation. A lot of Spring injection works like this with annotations but they are also used by many other frameworks such as Hibernate, Jersey, etc. The main idea is that annotations act as markers on specific code points to be used by an external entity at a later point.
I am making an address book application and I am brand new to aspectj and I am trying to use a variable int inside the aspect but eclipse is saying it "Cannot be resolved to a variable".
What do I need to do to use the variable? Thanks for any help you can give me.
Aspect
before(): execution(* *.deleteAddress(int <--PARAMETER I WANT TO USE))
{
fileServices.addXMLToFile(fileServices.makeXML(FileServices.map.get(WHERE I WANT TO PUT THE PARAMETER)), FileServices.ProductionFileName);
}
Here is the code if that will help
public void deleteAddress(int keyNumber) throws Exception
{
Address oldAddress = map.get(keyNumber);
map.remove(keyNumber);
addXMLToFile(makeXML(oldAddress), BackupFileName);
}
You need to use args() in order to bind positional parameters to advice method arguments.
The Spring manual explains that for Spring AOP (which is technically different, but shares a subset of syntax with AspectJ), but they syntax which is rather unusual for beginners, referring to pointcuts defined in in a different class.
Better read the AspectJ manual which also explains it. I just noticed you use native AspectJ syntax anyway, which means Spring AOP is not your topic. Let me just leave the reference in my answer for Spring AOP users.
In your case the answer - now in native AspectJ syntax again - would be (untested, just texting freestyle):
before(int keyNumber) : execution(* *.deleteAddress(int)) && args(keyNumber) {
fileServices.addXMLToFile(
fileServices.makeXML(
FileServices.map.get(keyNumber)
),
FileServices.ProductionFileName
);
}
I'm using the Datastax Java Driver Mapper.
The Doc and Github describe the possibility of using the #Select annotation with no parameters to select all rows within a table.
https://docs.datastax.com/en/developer/java-driver/4.4/manual/mapper/daos/select/
https://github.com/datastax/java-driver/pull/1285
So I did the following:
#Dao
public interface SchaduleJobDao {
(...)
#Select
#StatementAttributes (consistencyLevel = "LOCAL_QUORUM")
PagingIterable<ScheduleJobEntity> all();
(..)
However, an error is raised by Eclipse in the all() method line:
"Invalid parameter list: Select methods that don't use a custom clause must take the partition key components in the exact order (expected PK of ScheduleJobEntity: [java.lang.String])"
According to the references above, it should be allowed.
I did check the version, and prior 4.2 this feature should be working, I'm using the 4.4. So it doesn't seem to be version related.
My pom file:
<dependency>
<groupId>com.datastax.oss</groupId>
<artifactId>java-driver-mapper-processor</artifactId>
<version>4.4.0</version>
</dependency>
What I may be doing wrong? Is where a way to solve this?
Thanks
I think this might be a configuration issue. Could you check that your POM doesn't reference an older version of the processor in another place? In particular, another way to provide it is in the annotationProcessorPaths section of the compiler plugin, as shown here.
We have an integration test that covers this case and I just double-checked that it passes in 4.4.0. Also, the error message slightly changed after we introduced the feature, it used to say "must take the partition key components", now it says "must match"; you're quoting the old message.
Do you know, if there is the possibility to check who is calling a method and to restrict whether they are allowed to execute it with Java Annotations?
For example if you have a client and a server. There are several users, which have different roles and they login into the client. Then (the same client) with different users wants to call a getMethod on the server.
Can I restrict, who is allowed to call this methos with Java Annotations?
Like:
#Role(role="AllowedRole")
public ReturnType getMethod() {
...
}
Well, I used to achieve this with Seam/DeltaSpike in JBoss Server. It's pretty straightforward.
Basically, you have a method which you annotate with your annotation. For example, mine is #User:
public class MyClass {
#User
public Object getMethod() {
//implementation
}
}
Next, you need a class where you define how you check your annotations:
public class Restrictions {
#Secures #User
public boolean isOk(Identity identity) {
if (identity.getUsername("Peter")) {
return true;
}
return false;
}
}
That's it! Ofcourse, you need some libraries and to define these intercepting stuff in certain xml files (like beans.xml) but it can be easily done with a little googling.
Start from these links:
Seam framework
Questions I asked on JBoss community when I was starting with this
This seems to be a good case for Method Security of Spring Security.
Annotations do not include code and are not processed magically. They just define metadata, so you need some kind of engine that processes the annotations and performs the access validation.
There are a lot of frameworks and tools that do this. For example you can implement this using AspectJ, Spring framework and Java EE support similar annotations.
You can also implement this logic yourself using dynamic proxy, byte code engineering or other technique.
So, please explain better what kind of application are you implementing and we can probably give you better advice.
When experimenting with Spring MVC, I noticed the values passed to controller arguments annotated with #PathVariable will have all the characters from the last '.' on stripped, unless the last character is a '/'.
For example, given the following code:
#RequestMapping("/host/${address})"
public String getHost(#PathVariable String address, Model model) {
model.addAttribute("host", hostRepository.getHost(address));
return "host";
}
If the URL is "/host/127.0.0.1", the value of address will be "127.0.0". If the URL is "/host/127.0.0.1/", the value of address will be "127.0.0.1".
Is there away to prevent this stripping?
There are plenty of such reports in their issue tracker already (for example, SPR-5778). But they don't fix it, so it seems to be a legitimate behaviour.
The official workaround is to set useDefaultSuffixPattern = false on DefaultAnnotationHandlerMapping, but it has several drawbacks:
It is applied to all controllers
It completely disables extension handling (for example, for ContentNegotiationViewResolver)
It breaks "trailing slash doesn't matter" rule
More sophisticated workarounds use a customized PathMatcher, as described here.
It's apparently been handled as a file extension and stripped. Not sure if it's a bug. I would fill an issue at their issuetracker.
Update: please check this topic, it's actually not a bug and it can be solved programmatically: Trying to create REST-ful URLs with mulitple dots in the “filename” part - Spring 3.0 MVC