java - examples - struts2 framework
Cómo obtener un objeto DataSource gestionado por contenedor en Structs Action (1)
Soy nuevo en el uso de Struts 2 Framework.
Necesito usar DataSource Object en Struts Action Class. Mi plataforma es Tomcat 8 (Servlet 3.1) y configuré Resource en context.xml.
Puedo inyectar Container managed DataSource Object en un servlet usando @Resource annotation.
Lo intenté de esta manera. Creo un ServletContextListener e inyecto DataSource en este oyente. Establecí esta fuente de datos en el objeto de alcance de la aplicación en el método contextInitialized.
@WebListener
public class ResourceListener implements ServletContextListener {
@Resource(name="jdbc/skill_db")
private DataSource ds;
public ResourceListener() { }
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("Start");
sce.getServletContext().setAttribute("Datasource", ds);
sce.getServletContext().setAttribute("dbConfigStream", sce.getServletContext().getResourceAsStream("/WEB-INF/database.properties"));
}
@Override
public void contextDestroyed(ServletContextEvent sce) { }
}
Después de eso, tengo acceso al alcance de la aplicación y obtengo esta fuente de datos de los métodos de Acción de Struts.
public String welcome() {
Map<String, Object> application = ActionContext.getContext().getApplication();
DataSource ds = (DataSource) application.get("Datasource");
InputStream conf = (InputStream) application.get("dbConfigStream");
Model<Employee> empModel = new BaseModel<Employee>(Employee.class,
Employee::convert, ds, conf);
list = empModel.getAll();
return "welcome";
}
Mi pregunta es:
- ¿Puedo obtener el objeto DataSource en un objeto de acción de estructura?
- ¿Es así como traté de forma correcta en struts?
Probé mis requisitos con Struts2-CDI Plugin Al usar CDI puedo inyectar mis dependencias.
1. Edito POM de mi proyecto de la siguiente manera.
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-cdi-plugin</artifactId>
<version>2.3.24</version>
</dependency>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet</artifactId>
<version>2.2.15.Final</version>
</dependency>
2. Como utilicé Tomcat, necesito agregar estos códigos a context.xml y web.xml para usar CDI.
2.1 context.xml
<Resource name="BeanManager" auth="Container"
type="javax.enterprise.inject.spi.BeanManager"
factory="org.jboss.weld.resources.ManagerObjectFactory" />
2.2 web.xml
<resource-env-ref>
<resource-env-ref-name>BeanManager</resource-env-ref-name>
<resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
</resource-env-ref>
3. Producir Datasource
Inyecte directamente el objeto DataSource y el ServletContext en la clase ResourceProducer. De modo que no necesito una clase de escucha para establecer DataSource en el alcance de la aplicación y tampoco necesito acceder indirectamente al objeto de contexto de servlet.
El uso de CDI libera las limitaciones de Struts.
@ApplicationScoped
public class ResourceProducer {
@Resource(name="jdbc/skill_db")
private DataSource datasource;
@Inject
private ServletContext servletContext;
@Produces
@DbResourse
public DataSource getDatasource() {
return datasource;
}
@Produces
@DbConfiguration
public InputStream getConfiguration() {
return servletContext.getResourceAsStream("/WEB-INF/database.properties");
}
}
4. Inyectar DataSource en Model Producer
@Inject
@DbResourse
private DataSource ds;
@Inject
@DbConfiguration
private InputStream dbConfig;
@Produces
@DataModel(Employee.class)
public Model<Employee> getEmployeeModel() {
return new BaseModel<Employee>(Employee.class, Employee::convert, ds, dbConfig);
}
5. Modelo de inyección en Struts 2 Action Class
@Inject
@DataModel(Employee.class)
private Model<Employee> empModel;
public String welcome() {
list = empModel.getAll();
return "welcome";
}