We have a web application that is domain specific. By domain specific I mean that some values and behaviour are hard coded and not generic enough to handle new domain. So we are in a phase of abstracting the application and make it more open to new domain.
We are using maven, spring and JSP. The idea is to have a project that is generic and one project by domain that would contain the resources. The final application would be a combination of the generic app and one of the domain resources.
I identified different elements that we need to abstract, and wanted to know the best practices to achieve the abstraction using Spring.
Static HTML page like contact us information.
The current implementation is a controller method coupled with a contact.jsp page.
#RequestMapping("/contact.htm")
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) {
return new ModelAndView("contact");
}
Spring is looking for a page contact.jsp in /WEB-INF/jsp/contact.jsp.
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean
I added a new dependency that contains the contact.jsp. In my-resources.jar, I have the jsp file under /WEB-INF/jsp/contact.jsp. Is there a way to configure the viewResolver to fetch the file as a resource from the jar instead of fetching the file as a File on the file system?
UI
We have a radio button that allows the user to choose between several versions. Not all versions apply to all domain, so for one domain only 2 versions would be displayed, and for another domain, 4 versions would be displayed.
The idea is to create a property file in the my-resources.jar to configure the UI.
versions.supported = 2, 3
What is the best way to access the property file since it would be needed in almost all the controllers?
Because you are using maven, why not make your generic project package as war? This will solve your problem. Also you domain specific project can over ride generic project files if needed.I worked on a project with similar requirements. You will always find a case where you need to override generic project files.
Related
I am learning Spring MVC framework, and created a simple "Hello world" kind of web-application using Spring MVC framework.
My controller code is like this:
#Controller
public class SimpleController {
#RequestMapping("/welcome")
ModelAndView handleIncomingWelcomeReq() {
ModelAndView mw = new ModelAndView("WelcomePage","welcomeKey","WelcomeKey's value!");
return mw;
}
}
The spring configuration is:
<beans>
<context:component-scan base-package="com.example.controller, com.example.util"/>
<bean id="viewResolver1" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix"> <value>/WEB-INF/</value> </property>
<property name="suffix"> <value>.jsp</value> </property>
</bean>
</beans>
The code is straightforward, for /welcome , handleIncomingWelcomeReq() gets invoked and welcomePage.jsp is returned to the client.
For this simple application, we need to specifically mention the view page which it returns. Now my question is:
In real enterprise web-applications, how do we organise the view / page which gets returned for matching url. Wouldn't the spring configuration get too big, because we have to specifically mention the page which gets returned for each incoming url.
Is this the way Spring MVC builds the real life enterprise web application. Each page specifically mentioned in the spring configuration page?
Any inputs on this which help clarify this really appreciated.
The responsibility of defining the page flow specifically lies on individual controllers and views; for instance, you usually map a web request to a controller, and the controller is the one that decides which logical view needs to be returned as a response. This is sufficient for straightforward page flows, but when your application gets more and more complex (real enterprise web-applications) in terms of user interface flows, maintainance becomes a nightmare. If you are going to develop such a complex flow-based application, then Spring Web Flow can be a good companion. Spring Web Flow allows you to define and execute user interface flows within your web application.
Is it possible to specify complete path of a view file in controller without making use of view resolver?
Suppose I have just one file, say a XML file in my views and for a particular request I want to serve that XML file. By using view resolver, I am not able to find a way to pick up such a file and server it directly like me serve a jsp. So, for such a case can I do something in which I specify complete path in controller like we used to do in servlet's getRequestDispatcher?
My view resolver is currently configured for JSP only, I am not able to find a view using view resolvers to handle this situation, my view resolver is like as given below:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
Currently I am using getRequestDispatcher in controller for this? Is there any spring based alternative?
Spring MVC allows you to create a request handling method with different return types, see the reference guide. Instead of a String return a View from your method which points directly to your resource. When you return a View instance Spring MVC will not consult a ViewResolver but simply use the view as is. For you case you probably want to use an InternalResourceView.
#RequestMapping
public View yourRequestHandlingMethod() {
return new InternalResourceView("path/to/resource");
}
I have config xml based spring application for which I have moved proprties required at start up time in database. It was very difficult to manage hundreds in property file and that is why database is introduced. To read properties a spring restful service is developed to return a map of all properties required at start up time.
I want to know how to replace properties reading from a map to spring context file e.g. ${config.service.url} should be polulated from a map read via web service.
One option I considered is to upgrade to Annotation based and start using MapPropertySource and Environment interface as environment.getRequiredProperty("config.service.url"). However upgrading to Annotation based is a big impact on project and is no at this time.
Second option that I am looking forward is to have a customised PropertyPlaceholderConfigurer.
Any pointer/help on this will be great.
Cheers,
Amber
You could define a PropertyPlaceholderConfigurer, but instead of specifying a file location, you can pass the properties directly as returned by your restful service.
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" .../>
</bean>
I am working on a Spring MVC application in which I have recently been convinced to revamp my database code. Before I was using very traditional JDBC code that I have been told was very "old school" because of the boilerplate code. I have been making the transition to using JdbcTemplate with Spring.
I have configured a bean like shown below in my applicationContext.xml file.
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:ip-address:port/dbName"/>
<property name="username" value="myUsername"/>
<property name="password" value="mypassword"/>
</bean>
I have run tests just to make sure everything is working and it is.
My question is, I am aware that I am using the Commons DBCP package which uses the
following packages
commons-dbcp package
commons-pool package
Again, I am very inexperienced with this, so I apologize if I am mis referencing something or am explaining something incorrectly.
I have followed what most of the tutorials have said to do and specified a jdbcTemplate and injected the dataSource bean into it, but this doesnt really refer to my question.
What I would really like to know is, am I using ConnectionPooling with this configuration?
If so, is it being done behind the scenes, or do I need to specify to do it somewhere?
I have looked at the documentation at Here which gives the following, but I am not sure exactly how to interpret it.
"here are several Database Connection Pools already available, both within Apache products and elsewhere. This Commons package provides an opportunity to coordinate the efforts required to create and maintain an efficient, feature-rich package under the ASF license.
The commons-dbcp package relies on code in the commons-pool package to provide the underlying object pool mechanisms that it utilizes."
I also looked at the Configuration Page
and based on this page, I would think that I am able to do ConnectionPooling, but may need to specify additional parameters in my dataSource bean.
Can somebody please answer my questions or point me in the right direction?
Yes you are using connection pooling.
here is another thread you might find interesting
http://forum.springsource.org/showthread.php?t=40598
Also most of the links you specified above will provide additional information on parameters that can be set.
Seems like a simple task. I have a webapp which requires a database connection. I'd like to be able to drop an updated .war file on this app server and load a new version without having to re-edit an applicationConfig.xml file to specify the database connection parameters for production.
Is using the container to setup the data source and then referencing it from JNDI the preferred way to go? I think it is cleaner having it all defined in the spring .xml file, but I can't come up with a clean way to allow the production password to be set only once as we roll out new versions.
So, how do you specify your database connection information in a spring application so that you can upgrade it without having to re-edit the files?
If you use JNDI, how do you handle setting up of your tests since the JNDI is not going to be available outside of the container?
Thanks!
The typical way to externalize database connection properties is to store them in a .properties file and load using <context:property-placeholder .../> . Then you can have different .properties files for testing and production.
If you choose JNDI, you can use a Spring's mock JNDI support for testing.
One approach is for your Spring configuration file to be composed of fragments related to specific layers in your application.
One such fragment could contain your DataSource defintion. For production, this fragment would use a jee:jndi-lookup. And then for test, have a different fragment would use a DriverManagerDataSource ?
Update:
If you want to change the datasource after deployment, then you can use this technique, along with changing the which datasource is injected into your other beans using a PropertyPlaceholderConfigurer as explained in an old post I wrote
eg:
<bean class="foo.bar.SomeClassNeedingDataSource"">
<property name="dataSource" ref="${the.datasource.to.inject}" />
</bean>
<jee:jndi-lookup id="jndiDataSource" ... />
<bean id="driverManagerDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
...
</bean>
# the properties file
the.datasource.to.inject = jndiDataSource
#the.datasource.to.inject = driverManagerDataSource