Spring #RequestMapping value explicit/implicit - java

In some cases I have seen two different ways to specify uri in #RequestMapping:
#RequestMapping(value="/somepath")
#RequestMapping("/somepath")
The latter is often used at class level. So, is it always legal omitting the value attribute?

The Java Language Spec states
It is legal to use single-element annotations for annotation types with multiple elements, so long as one element is named value, and all other elements have default values.
Since #RequestMapping has a defined value attribute and all other attributes have default values (empty arrays), it is always legal to omit spelling the name value if you don't specify any other attributes for the annotation:
#RequestMapping("/somepath") // valid
#RequestMapping("/somepath", method = RequestMethod.GET) // INVALID!

For #RequestMapping annotation value is the primary attribute, it is mandatory.
1)#RequestMapping(value="/somepath"):
Here you can mention remaining attributes, for ex: method,produces
2) #RequestMapping("/somepath"):
Here you can not mention rest of the attributes, as by default "/somepath" will be taken as value attribute.
Check this

Related

Why does PropertyDescriptor return a property name with uppercase as first character?

I'm obtaining an information about a class via
Introspector.getBeanInfo(this.getClass()).getPropertyDescriptors()
then getting the property's name by invoking propery[i].getName().
Everything is fine if a property has no one-letter-part. For example, if a property has a name personAddress (meanwhile its getter/setter -> getPersonAddress(), setPersonAddress(String personAddress)), is's OK, getName() returns personAddress.
But if the property has a name rPersonId (getRPersonId(), setRPersonId(Long rPersonId)) then getName() returns "RPersonId", i.e. first letter has been capitalized! Why?
According to this: https://docs.oracle.com/javase/7/docs/api/java/beans/FeatureDescriptor.html:
public String getName()-> Gets the programmatic name of this feature.
So why does it return a name somehow related to its getter's or setter's name instead of the real name of the property?
This is actually the documented behaviour.
First of all, property names are entirely located by discovering their getter and setter, and not by looking at the fields of the class. This is specified in paragraph 8.3 of the Java Beans specification:
If we discover a matching pair of get<PropertyName> and set<PropertyName> methods that take and return the same type, then we regard these methods as defining a read-write property whose name will be <propertyName>.
So when you have the introspection of a class that contains Long getRPersonId() and setRPersonId(Long), a property can be extracted from it. The name of the property generally follows from lower-casing the first letter, and keeping the rest unchanged. But this is not always the case, the exact rule is in paragraph 8.8:
Thus when we extract a property or event name from the middle of an existing Java name, we normally convert the first character to lower case. However to support the occasional use of all upper-case names, we check if the first two characters of the name are both upper case and if so leave it alone. So for example:
FooBah becomes fooBah
Z becomes z
URL becomes URL
We provide a method Introspector.decapitalize which implements this conversion rule.
In the example above, the getter and setter would provide the String RPersonId to turn into a property name. Since the first two characters are upper-case, the first character will not be lower-cased. As such, the property name that will be derived is RPersonId, and this explains your output.
You can also call the method decapitalize to see which property name would be located from a pair of getter / setter:
System.out.println(Introspector.decapitalize("RPersonId")); // prints RPersonId
System.out.println(Introspector.decapitalize("PersonAddress")); // prints personAddress
Because this is part religion.
The people who did Java Beans felt that properties should ALWAYS be accessed by a pair of methods. So you are NOT getting the name of the data member. You are getting the property which can only be accessed by the methods.
This is from the documentation:
A PropertyDescriptor describes one property that a Java Bean exports
via a pair of accessor methods.
https://docs.oracle.com/javase/7/docs/api/java/beans/PropertyDescriptor.html
The theory was you should never use the data member name, and so through the Bean interface, they don't give you that.

Java Spring #RequestMapping annotation

Why am I able to use this annotation - give it a value without specifying which element I'm assigning this value to? For example, I can write: #RequestMapping("/home") instead of #RequestMapping(value="/home").
The specs do not mention anything about it. Is it just a behaviour of Java annotations treating the field value as default one?
Case #1: If you have a single value then it's optional to write like this:
#RequestMapping(value="/home")
In this case you may write
#RequestMapping("/home") also. While providing a single string this is automatically assigned to "value". [ default behavior ]
Case #2:
#RequestMapping has a String[] value parameter, so you should be able to specify multiple values like this:
#RequestMapping(value={"","/", "/away", "/home"})

How to pass multiple parameters using html link in Struts1.x

I am trying to pass multiple parameters to my Struts action class using <html:link> property.
I am having a link, it should take two parameters from the JSP page to my action class.
How to achieve this?
In Struts 1.3 parameters could be set to the action attribute like in this example
<html:link action="/path/to/action?param1=2&param2=${param2Value}">Some text</html:link>
Quote from the documentation:
If you prefer to specify a java.util.Map that contains all of the request parameters to be added to the hyperlink, use one of the following techniques:
Specify only the name attribute - The named JSP bean (optionally scoped by the value of the scope attribute) must identify a java.util.Map containing the parameters.
Specify both name and property attributes - The specified property getter method will be called on the bean identified by the name (and optional scope) attributes, in order to return the java.util.Map containing the parameters.
As the Map is processed, the keys are assumed to be the names of query parameters to be appended to the hyperlink. The value associated with each key must be either a String or a String array representing the parameter value(s), or an object whose toString() method will be called. If a String array is specified, more than one value for the same query parameter name will be created.
Supplmenting these two methods, you can nest one or more tags to dynamically add parameters in a logic-friendly way (such as executing a for loop that assigns the name/value pairs at runtime). This method does not compete with the aforementioned; it will adds its parameters in addition to whatever parameters are already specified.
You can also use a regular HTML <a> tag and create the URL using the standard <c:url> tag from the JSTL.
why don't you go with ajax calling ? by using ajax you can pass many parameter to action class by set the method K

What are <required> and <rtexprvalue> used for?

I was working on custom tag libraries and I was confused how the <required> and <rtexprvalue> tags are used in the TLD file to define a custom tag attribute.
What are these tags?
What should we write in-between them?
What behavior do we get after writing these tags?
required quite simply implies what it says. The attribute is required or mandatory.
rtexprvalue means Runtime Expression Value. It means the attribute can support scriptlet values.
elexprvalue means it can support EL (expression language) values.
So, if you have requiredattr defined as both required=true and rtexprvalue=true and elattribute is defined as elexprvalue=true, you can write as follows:
<myprefix:mytag requiredattr="<%=baz.getId()%>" elattribute="${foo.bar}"/>
The <rtexprvalue> element defined in a TLD captures the dynamic behavior of an attribute. The
value can be either true or false. A false value in the dynamic column means that
only a static string value can be specified for the attribute. A true value means that a
request-time attribute value can be specified. As defined in the JSP specification, a
“request-time attribute value” can be either a Java expression, an EL expression, or a
value set by a <jsp:attribute>.
The <required> element defines if the nesting attribute is required or optional. If not present then the default is "false", i.e the attribute is optional.

Is 'value' a java keyword?

It seems to have a special meaning in annotations - it allows you to skip the parameter names when instaniating an annotation.
#Foo(bar = "abc") // a normal instantiation of an annotation
#Foo("abc") // if bar were renamed 'value'
Where is this documented? Is value a keyword or not? See also.
It's not a regular keyword, as it's not listed in section 3.9 of the JLS. In particular, you can use it as an identifier anywhere you like, as far as I'm aware.
The use of value by default for an annotation value is specified in section 9.7:
The third form of annotation, single-element annotation, is a shorthand designed for use with single-element annotation types:
SingleElementAnnotation:
# TypeName ( ElementValue )
It is shorthand for the normal annotation:
#TypeName ( value = ElementValue )
No, value is not a keyword in Java. If only one parameter is given to an annotation and that annotation only has one element that is called value, then the name value can be omitted when using the annotation. Annotations are explained here:
http://download.oracle.com/javase/1.5.0/docs/guide/language/annotations.html
And documented in section 9.7 in the JLS:
value is the default field into which annotation data is placed. value however is not a java keyword (thanks for the reminder #gustafc).
This is documented where you would expect it to be - in the official documentation, which states:
In annotations with a single element, the element should be named value
and
It is permissible to omit the element name and equals sign (=) in a single-element annotation whose element name is value

Categories