Is it possible to make spring mvc project as a Jar dependency? - java

We are using Spring MVC to build our application, and we tried to use ajax for communicating with the server, we only render the basic pages by apache tiles.
And there a couple of modules, for example:
app-data will be responsible for some data uploading,processing and persisting. And the url mapping may looks like:
restful-like service:
/api/data/excel (post,get,delete)
/api/data/pdf (post,get,delete)
pages:
/data (home page for the data module, return a rendered html page)
app-user will be responsible for user managing, url mapping:
restful-like service:
/api/user (post,get,delete,put)
pages:
/user (home page for the user module, return a rendered html page)
app-site will be responsible for the other pages like:
/about
/contact
/feedback
.....
BTW, we have another reason why we split them to different modules, some of the modules maybe re-used in other projects. We want all the pages and restful services re-used.
Now this is the application structure at the moment:
app
app-data
build.gradle
src/main
java
resources
app-user
build.gradle
src/main
java
resources
app-site
build.gradle
src/main
resources
webapp
static
WEB-INF
jsps
header.jsp
footer.jsp
tiles
data.jsp
user.jsp
We expected the final application to be bundled with a war package contains the following content:
app
static
WEB-INF
classes
xx.properties
lib
app-data.jar (with resources including *.properties)
app-user.jar (with resources including *.properties)
jsps
.....
And what's more, different modules may contains some different configurations by the *.properties, and we want to override some of them for example, once we have a new project, and we need the user feature, we copy the app-site and app-user, and override the properties in /app-site/src/main/resources/*.properties, then it is done.
I wonder if this is possbile?
Update:
I am not trying to make the app-site as as jar(thought it is possible with spring boot or something else), the app-site itself is still a war project, while its dependencies (app-data and app-user) are bundled as jars.

I think you can easily package controllers in different jars which according to me is not problem in your case however issue will be with static contents like js, css and html. To serve them to browser you have to mark them mvc resource. Lets suppose you jar is follow below structure.
src
main
java (all controllers)
resources
webcontent
css
js
app.js
As show above static content is in resources/webcontent folder. It can be served as mvc resource as below.
<mvc:resources mapping="/resources/**" location="classpath:/webcontent/"/>
You can get app.js in your html as below
<script type="text/javascript" src="js/app.js"></script>

Related

Allow Apache's FreeMarker template engine to load templates from outside Resources folder

I created a Spring Boot Application using Spring Initilizr. I then included Apache's Freemarker template engine to load the templates from my project. The engine by default loads templates from: src/main/resources/templates/ folder.
I am trying to load a simple index.ftl file as template when the user visits the webpage http://localhost:8080. But I need to load the templates from src/main/webapp/ folder. Whenever I try to load the templates from outside the resources folder, the template engine fails to find the templates.
I have gone through various tutorials and Stack Overflow questions. None answer my question and I'm stuck with a 404 ERROR because the engine is not able to find the files.
The file structure is:
|-src
|---main
|-----java
|-------MainApplication.java
|-------controllers
|---------ViewController.java
|-----resources
|-------static
|-------templates
|-------application.properties
|-----webapp
|-------index.ftl
After a lot of digging, I came across a post where they suggested changing the location where the template engine searches the files. It suggested adding following lines in application.properties:
spring.freemarker.enabled=true
spring.freemarker.template-loader-path=classpath:src/main/webapp/
This doesn't seem to work at all.
I am trying to resolve simple index page when I visit the webpage at http://localhost:8080. I've written following code for mapping the HTTP request in ViewController.java:
#RequestMapping("/")
public ModelAndView home(Model model)
{
return new ModelAndView("index");
}
No idea if I am totally getting it wrong or I've missed some configuration.
From Spring docs:
Do not use the src/main/webapp directory if your application is
packaged as a jar. Although this directory is a common standard, it
works only with war packaging, and it is silently ignored by most
build tools when you generate a war.
src/main/webapp is associated with web archive and will be packaged by maven war plugin when you generate the war.
Assuming you require a separate location to keep ftl templates and you would still like to package as jar you could follow below steps.
Add the resource entry in the build in pom file so resource plugin can copy that directory to classpath.
<build>
<resources>
<resource>
<directory>src/main/webapp</directory>
</resource>
<resources>
<build>
Change the loader path to read from the ROOT of classpath.
spring.freemarker.template-loader-path=classpath:
If its only for ftl templates I would change the directory to src/main/ftls to avoid confusion and update the same in the resources.
UPDATE
I actually wanted to build a WAR deployment package
You have to use war plugin to build war. Add the plugin and change the packaging to war in pom.
More about the Traditional Deployment: https://docs.spring.io/spring-boot/docs/current/reference/html/howto-traditional-deployment.html#howto-create-a-deployable-war-file
EDIT
In embedded tomcat you can define static resources path in application-properties
spring.mvc.static-path-pattern=
If you deploy to tomcat, in tomcat use can define inside server.xml static context that can hold freemarker files, as
<Context docBase="/home/stuff" path="/static" />
A <Context> element is added inside the <Host> element. Context has two attributes: docBase is the directory on disk that contains your static files and path is the URL that you want to serve the files on.

Spring Boot does not load Bootstrap in jsp file

Today i have a problem with Bootstrap in my Spring Boot app.
Spefically, when i start the app and open the browser, i can see my page but with "classic" html; that is, i don't see the page formatted with the css of Bootstrap but with normal html5 (so, Bootstrap is nota loaded).
What i have done?
First, i've download Boostrap framework; then i try to put the 3 folder css, js and fonts under both this path:
src/main/webapp (first)
src/main/resource/static (then)
In the second case, i tried also to move from /static folder into resource, that is src/main/resource
When i've put this 3 folder in resource and resource/static, i tried 2 configuration:
add in application.properties file this line of code: spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
Use a MvcConfiguration class that extends the WebMvcConfigurerAdapter class and override the method addResourceHandlers this way:
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
}
Of course, done this, in my jsp file (located under src/main/webapp/WEB-INF/jsp) i'v put the 2 line of code to tell the page where take the css and js file:
<link href="/resources/static/css/bootstrap.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="/resources/static/js/bootstrap.min.js"></script>
and of course, these line change from /resource/static/ with /webapp when i try to put under src/main/webapp the 3 Bootstrap folder. But, after this, i cannot see Bootstrap loaded. What i wrong?
Update: solved. The problem was based on a setting in my applications.properties:
server.port=8080
server.contextPath=/polaris
that is, the change of the context path. A usefull tread on this site is this: Spring 4 - addResourceHandlers not resolving the static resources
Using in JSP by link href and give path like static/css/somename.css
Do 4 Step:
1.maven-Clean
2.update project
3.maven install
4.Run As Spring Boot App
Hope it will help.
The Path Of Any CSS Should be Like This in Spring Boot
You can refer following link for spring boot with boostrap template on web application. example_link. You have to change following property values on application.properties file inside the above application for jsp page load. Make sure inside webapp folder having correct name.
spring.mvc.view.prefix=/html/
spring.mvc.view.suffix=.html

My CSS doesn't show if i put my CSS folder inside the WEB-INF folder

I'm working in a Spring MVC project and I have the following problem:
This is my folders hierarchy
--src
--main
--webapp
--WEB-INF
--views
--css
--mystyle.css
---myview.html
and this is how I call mystyle.css in myview.html
href="css/mystyle.css"
but my CSS doesn't show up.
But if I put my views folder outside of WEB_INF, my CSS does show up and it works like this:
--src
--main
--webapp
--views
--css
--mystyle.css
--myview.html
--WEB-INF
And I call my CSS the same way like before href="css/mystyle.css"
Is there something different that I didn't notice? Why doesn't my CSS works outside of the WEB-INF folder and it does not work inside?
While it is true that you cannot access resources under WEB-INF folder directly, you can still keep your location and add a configuration like
<resources mapping="/css/**" location="/WEB-INF/views/css/" />
in your spring mvc configuration, or a java config equivalent if you're using java config. Note that you should be accessing css with an absolute URL, so if you're serving from root
href="/css/mystyle.css"
or prepand a context if you're using one
Right, CSS files need to be in a path that is directly visible to the browser. WEB-INF is hidden.

Struts 2 Validation failing when Action class sits in a separate jar file

I have a maven multi-module project.
project-services (service layer..above the dao layer)
project-controller (My Action classes sits in this module)
project-web (all jsps, view artificats)
The issue is I have a valid DefaultProjectsAction-validation.xml in the package with DefaultProjectsAction.java as well as the properties file.
All these modules, when the war file is deployed will be in /WEB-INF/lib. I use in struts.xml the default package. All files are correctly set-up. Spellings errors on the the file names checked properly. Will my struts validations work if the validation xml files are in a seperate jar. I read somewhere where they say it should be in WEB-INF/classes/. Is this the reason why my struts form can't be validated?
Ok it's exactly 48 hours since I started looking at this problem and ladies and gentlemen the solution has been found.
Putting struts 2 action classes on a seperate module and validation set-up has to go like this.
project-controller (will have action classes for Struts 2 in this case)
- com.pack.UserAction.java
The solution is to create a source folder src/main/resources/com/pack (Maven project) in project-web module and put UserAction-validation.xml in there. Like this
project-web (views, jsps, properties files and set-up files)
- src/main/resources/com/pack/UserAction-validation.xml
The file will be copied to /WEB-INF/classes/com/pack (The action class package should form the path) and on building the project

How to change location of static file in WAR archive?

By default static files are located in WEB-INF directory (accessible as /images/logo.png):
foo.war
WEB-INF
web.xml
images
logo.png
I want to change the structure and use this one instead (still accessible as /images/logo.png):
foo.war
WEB-INF
web.xml
static
images
logo.png
How can I do this with web.xml?
The container will repsond with a 404 NOT FOUND error if you directly access the files under WEB-INF using HTTP GET .
But now , you said you can access WEB-INF/images/logo.png by /images/logo.png , so I think your web application most probably achieve this result by some URLRewriteFilter mechainsim or by some Java code in the servlet level (eg a filter) , or by your web application 's framework . I suggest you to check your web application to see what mechanism causes this behvaior now and configurate to your desired result accordingly.
According to http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/WCC3.html,:
A WAR has a specific directory
structure. The top-level directory of
a WAR is the document root of the
application. The document root is
where JSP pages, client-side classes
and archives, and static Web resources
are stored.
The document root contains a
subdirectory called WEB-INF, which
contains the following files and
directories:
web.xml: The Web application
deployment descriptor Tag library
descriptor files (see Tag Library
Descriptors) classes: A directory
that contains server-side classes:
servlets, utility classes, and
JavaBeans components lib: A
directory that contains JAR archives
of libraries (tag libraries and any
utility libraries called by
server-side classes).
You can also create
application-specific subdirectories
(that is, package directories) in
either the document root or the
WEB-INF/classes directory.
So the default behavior is what you're looking for. Is your document root set incorrectly to serve content from WEB-INF?
You may use a filter or URLRewriteFilter to point /images/* to /static/images/*.
If you just want your folder structure to be /static/images for development time organization purposes, but the deployment URL to be /images -- you may need to alter your build script to copy /static/** to /.
I personally would not bother whether my static files are referred as /static/images or /images -- because they would be referred in my code (only), which I have control over.
If you are using these files in CSS and that's why you wanted the path to stay the same... better keep the images under /static/css/images and have the images that are referred in the CSS here. In this way, no matter where you move your CSS folder, you would not bother spoiling your CSS.

Categories

Resources