I have a class MyBean with some fields including String "id".
I have a lot of xml-defined beans with IDs.
I want to fill "id" fields of MyBean java objects to xml-specified bean IDs. How to implement this without code duplicaton?
package just.artmmslv.example.MyBean
public class MyBean {
private String id;
private String foo;
//getters, setters, other fields
}
<beans xmlns="foobar+util">
<util:list value-type="just.artmmslv.example.MyBean">
<bean id="exampleBean01" class="just.artmmslv.example.MyBean">
<property name="foo" value="bar"/>
</bean>
<!--Other beans-->
</util:list>
</beans>
So, how to make exampleBean01`s field id to be equal to "exampleBean01" in convenient way?
Make id in MyBean of type String, not int (I see int in your code)
Make MyBean implements BeanNameAware
Implement method setBeanName in MyBean:
#Override
public void setBeanName(String s) {
this.id = s;
}
That's all you need
I think Spring provides a way to do this via BeanNameAware.
Read through: https://docs.spring.io/spring/docs/2.5.x/reference/beans.html#beans-factory-aware-beannameaware
Interface to be implemented by beans that want to be aware of their bean name in a bean factory. Note that it is not usually recommended that an object depend on its bean name, as this represents a potentially brittle dependence on external
configuration, as well as a possibly unnecessary dependence on a Spring API.
Related
It might be a very simple question; but since I am a beginner into Spring, I cannot understand how to assign values to Spring beans at the run time.
I followed some tutorials for learning Spring and now I know how to get started with Spring. I can understand the Spring beans.xml where the bean definition is declared, I can understand some annotations which can be used instead of xml configurations. But I cannot understand how to do the following configuration.
Let's say I have a class called Student. Each student object has a name and an age.
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.address = address;
}
}
This is how will I write the entry in the Beans.xml file for bean configuration
<bean id="student" class="Student">
<property name="name" value="Joe"></property>
<property name="address" value="12"></property>
</bean>
I am completely okay with this setter injection. As far as I can change the property values using the xml file,I can change the properties of the student.
But let's think we need an application to register students. Using front end form of the application, we enter name and age. My question is how can we inject those name and age values to a Student bean. Now we are dealing with a running application.
I can't understand how should we change the xml to accept the user inputs(if it is the way of doing). In all the beginner tutorials I followed, I didn't find a way to handle such situations. What they teach is what I already know.
I think I am missing some lesson on this. Please guide me to solve my problem. Some example code will be much helpful for me to understand if possible.
Thank You..!
You dont find any tutorial for your problem because your usecase is not sutable for spring. In practice we dont use spring to achieve what you are trying to do. Spring is best suitable for dependency injection of classes with singleton behaviour for example service classes for which you will generally need single instance across your application.
Generally we use ORM like hibernate for the use case which you are ferering to.
Beans are not suitable for Value Objects, which is why your approach is not working.
Beans are instantiated classes that will have long running lives during the execution of your program, they are managed by Spring. This includes instances of classes that provides business logic or classes that provide program functionality, like database connections or a socket server.
Value Objects are short lived data object instances that is used by your application, which the student class seems to be. They are managed by your program code.
I have an object in API jar, that I cannot change:
public class User {
#NotNull
private String name;
#NotNull
private String password;
}
In my code I need to use this object and to validate data inside, but, for example, I would like to let the password be empty. I cannot remove #NotNull from the class (and I cannot define groups for given constraint). How can I influence the validation without redefinig it from scratch?
One possible solution is to override the constraint definition of the specific class using either the constraint-mapping xml file or the Hibernate Validator specific API.
As described in the documentation, you can overide specific annotations (like the password field annotation) and leave the others untouched.
<constraint-mappings ...>
<bean class="User" ignore-annotations="false">
<field name="password" ignore-annotations="true">
... new annotations
</field>
</bean>
</constraint-mappings>
further reading:
http://docs.jboss.org/hibernate/validator/5.1/reference/en-US/html/chapter-xml-configuration.html#section-mapping-xml-constraints
http://docs.jboss.org/hibernate/validator/5.1/reference/en-US/html/validator-specifics.html#section-programmatic-api
I've asked this question in my previous post here: SpEL for spring security: Passing Values from XML to Java based SpEL configuration. But it wasn't yet resolved. I want to inject values either from an xml configuration or from external file into #PreAuthorize(...) annotation. It is not easy like injecting by using #Value annotation.
To recall the question, I provide the following information.
I have the following xml configuration file (example.xml) that
has properties and initialized its corresponding values.
<beans>
<bean id="userBean" class="x.y.User">
<property name="name" value="A"/>
<property name="userId" value="33"/>
<bean id="customerBean" class="x.y.Customer">
<property name="name" value="B"/>
<property name="customerId" value="33"/>
</bean>
</beans>
I have the following external properties file
(example.properties) inside /WEB-INF folder. This file is an
alternative for the XML configuration file mentioned above.
user.id = 33
customer.id =33
I have property policy holder configuration in my applicationContext.xml file
<context:property-placeholder location="/WEB-INF/*.properties" ignore-unresolvable="true" />
<bean id="propertyConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/example.properties" p:ignoreUnresolvablePlaceholders="true" />
I have two model classes: User and Customer
public class User {
private int userId;
public int getUserId() {
return userId;
}
}
public class Customer {
private int customerId;
public int getCustomerId(){
return customerId;
}
}
I have another service/controller class which I want to restrict
the 'edit' method by using #PreAuthorize annotation.
The restriction: The method is allowed (authorized to be executed)
if and only if 'userId' and 'customerId' are evaluated equal!.
To achieve the restriction, I want to consider two ways
by injecting 'userId' and 'customerId' values from the xml file(example.xml) into expression 1 below. The expressions I used in
this are suggested by Rob Winch (Thank you Rob!). However, Spring
couldn't evaluate the expression.
by injecting 'userId' and 'customerId' values from the external properties file(example.properties) into expression 2
below. Similarly, spring couldn't evaluate this expression as well.
#Service("..") or #Controller
public class MyMainClass {
//Expression 1
#PreAuthorize("#userBean.userId == #customerBean.customerId")
public Boolean edit(User user, Customer custmer) {
return true;
}
//Expression 2
////I've tried other ways as well, but end up with similar exceptions
#PreAuthorize("${user.id} == ${customer.id}")
public Boolean edit(User user, Customer customer) {
return true;
}
}
My questions:
Q1. What are the right expressions that I must put inside the #PreAuthorize annotation to inject values from the xml file (example.xml) or from property file (example.properties) into the #PreAuthorize(...) expression, then it can be easily evaluated?
Q2. Point me if I did mistakes other than the expressions.
Q3. Its like a $1,000,000.00 question for me as I am fed up as hell to solve this issue!!!. So please help me out as much as you can!.
if you are using properties file and you want to access them in controller classes you have to add <context:property-placeholder location="classpath:my.properties"/> in your servlet context xml file, after that you can use #Value annotation to get the values of that properties. e.g.
my.properties file contains some.userid=33 so you would access this property using:
#Value("${some.userid}")
private int someId;
but to be sure for testing purpose i would set ignoreUnresolvablePlaceholders to false and in case it can't resolve properties file i would know where the error is coming from...
hope it helps.
This is my eventAction ActionSupport Class
public class EventAction extends ActionSupport {
protected EventService eventService;
protected String redirectUrl;
public String getRedirectUrl() {
return redirectUrl;
}
public void setRedirectUrl(String redirectUrl) {
this.redirectUrl = redirectUrl;
}
public void setEventService(EventService services) {
this.eventService = services;
}
}
And here is a fragment from my applicationContext.xml
<bean id ="eventService" class ="services.EventService" scope ="singleton">
<property name = "sessionFactory" ref = "sessionFactory"/>
</bean>
The code is working fine except for when I change the id inside the declartion.
My question why does spring <bean id ="eventService"> id has to be matched with eventService instance variable inside EventAction support class? isn't id is just making an identifier for the bean that is going to be created? why should the id inside the bean tag should be the same inside my EventAction, where the EventAction class is not even being mentioned in the configruation?
From Spring docs beans-beanname
Every bean has one or more ids (also called identifiers, or names; these terms refer to the same thing). These ids must be unique within the container the bean is hosted in. A bean will almost always have only one id, but if a bean has more than one id, the extra ones can essentially be considered aliases.
When using XML-based configuration metadata, you use the 'id' or 'name' attributes to specify the bean identifier(s). The 'id' attribute allows you to specify exactly one id, and as it is a real XML element ID attribute, the XML parser is able to do some extra validation when other elements reference the id; as such, it is the preferred way to specify a bean id. However, the XML specification does limit the characters which are legal in XML IDs. This is usually not a constraint, but if you have a need to use one of these special XML characters, or want to introduce other aliases to the bean, you may also or instead specify one or more bean ids, separated by a comma (,), semicolon (;), or whitespace in the 'name' attribute.
I believe for Spring-Struts2 you are using the plugin where you need to either define auto-wire strategy or plugin will use default one which is name.
That means when plugin bridge between Struts2 and Spring it will try to inject beans based on the supplied auto-wire strategy
Refer to Struts2 Spring-plugin
It is often useful to have a field in a DAO whose value comes from a Java enumeration. A typical example is a login DAO where you usually have a field that characterises the user as "NORMAL" or "ADMIN". In Hibernate, I would use the following 2 objects to represent this relationship in a (semi-)typesafe way:
class User {
String username;
String passwd;
UserType type;
}
class UserType {
private enum Type {ADMIN, NORMAL};
private String type;
//Setters/Getters for Hibernate
public void setType(String type);
public String getType();
//Setters/Getters for user
public void setUserType(UserType.Type t);
public UserType.Type getUserType();
public static UserType fromType(UserType.Type t);
}
This works, but I find the UserType class ungly and requiring too much bureaucracy just to store a couple of values. Ideally, Hibernate should support enum fields directly and would create an extra table to store the enumeration values.
My question is: Is there any way to directly map an enumeration class in Hibernate? If not, is my pattern for representing enumerations good enough or am I missing something? What other patterns do people use?
using hibernate or JPA annotations:
class User {
#Enumerated(EnumType.STRING)
UserType type
}
UserType is just a standard java 5 enum.
I can't imagine this is just limited to just annotations but I don't actually know how to do this with hbm files. It may be very version dependant, I'm guessing but I'm pretty sure that hibernate 3.2+ is required.
edit: it is possible in a hbm, but is a little messy, have a look at this forum thread
From the Hibernate documentation: http://www.hibernate.org/272.html
You can create a new typedef for each of your enums and reference the typedefs in the property tag.
Example Mapping - inline <type> tag
<property name='suit'>
<type name="EnumUserType">
<param name="enumClassName">com.company.project.Suit</param>
</type>
</property>
Example Mapping - using <typedef>
<typedef name="suit" class='EnumUserType'>
<param name="enumClassName">com.company.project.Suit</param>
</typedef>
<class ...>
<property name='suit' type='suit'/>
</class>