How to override AutoConfiguration in Spring? - java

I have followed the Spring example Serving Mobile Web Content with Spring MVC and got it working.
Now I would like to replace greeting.html with a simple static page (and replace Thymeleaf with a simpler view handler).
What is the easiest approach in this particular case?
I am new to Java, the probable solutions in web use web.xml, whereas this example does not use web.xml and it does not seem to be the recommended approach in Spring Boot documentation either. So, use #EnableAutoConfiguration with some overriding? How?

All you have to do is put the static HTML file in a place where Spring Boot will automatically look for static resources. This part of the documentation provides all the details.
So for example you can place your greeting.html under /src/main/resources/static/ and you will be able to access it at http://localhost:8080/greeting.html (that's if you have not configured a different port of the root path of the servlet context)

Related

Should I use ServletDispatcher when trying to make an angular webapp, with no jsp pages?

I have medium knowledge on how to make java webapps, and jsp pages. I am trying to extend my expertise, by learning how to use Spring MVC, AngularJS and RESTful api's.
I am having trouble drawing the lines between the dots. First of all, from what I have read, there should be no real need for jsp pages, when trying to do pure angularJS. So I'm trying to not use jsp's this time.
I am pretty much trying to make two html-pages, each with a link to the other. Now in a completely basic Spring MVC setup, this would be done with the help of two controllers, and the ServletDispatcher. In the servlet-context.xml (default name) I could probably change the default suffix from .jsp to .html, but I have read that I should treat static html pages as resources, instead of views, as they do not need the powers of a servlet.
The thing is, I have never made any kind of web page which didn't utilize a dispatcher, or front controller servlet, and although it might be completely obvious to most, I do not know what the alternative is. I am very in doubt if I am supposed to use the ServletDispatcher at all, and what the alternative is. I kinda thought the ServletDispatcher, and front controller pattern implementation was one of the most central parts of Spring...
So should I use the ServletDispatcher for an Angular web application, or should I just use Spring to make the RESTful api?
Spring framework allows you to serve static resources using ResourceHttpRequestHandlers which stores registrations of resource handlers for serving static resources such as images, css files and others through Spring MVC including setting cache headers optimized for efficient loading in a web browser. Resources can be served out of locations under web application root, from the classpath, and others.
Since you already have a basic spring MVC setting and running, then you need to configure your angularJS-app as a static resources, you can choose to keep your angularJS application folder under webapp folder, and continues your angularJS development there and you don`t need any JSP there.
Configure ResourceHttpRequestHandlers
with XML
<mvc:resources mapping="/app/**" location="/app/"/>
with Java config
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/app/**").addResourceLocations("/app/");
}
}
Now you can access your angularJS app as http://localhost:8080/context-root/app/
Your API development will continue as well in your spring MVC controllers.
Here is a great youtube series of Web Development Using Spring and AngularJS
Use AngularJS to make static web pages(HTML+CSS+JS+other static resources).
Use Servlet to make RESTful API.(Restlet framework is recommended to make RESTful API, it can run as a standalone java app or integrate into Servlet to run in Tomcat.)
JS will call RESTful API to get data and update the page view.

Runtime loading of Controllers for Spring MVC and dynamically mapping requests/URLs

We are starting a new project using Spring MVC, and we would like to move away from annotation-driven request/url mapping. We wish to implement the following use case:
Use Case A
User enters a URL.
The request mapping handler retrieves a list of mappings (e.g. from the DB), and based on this dynamic list of mappings, it calls the relevant controller.
This is because we want to be able to do the following as well:
Use Case B
We want to load a new Controller (perhaps a new reports module) into the web app without having to redeploy or do a server restart.
We will map this new Controller to a URL and persist it somewhere (most likely the DB).
We would like the Controller to be registered in the Spring app context (managed by Spring).
We would then like to use this new Controller in the request mapping.
We've taken an initial look at the different ways we can implement this, but we are unsure of the best architecture/method to go about this route. A couple of questions:
For Use Case A, how do we implement this within the Spring MVC framework (or if it's possible)?
For Use Case B, is there a good framework or way to be able to do dynamically loading and registering of this for web applications? We've taken a cursory look at OSGI but it seems to be advisable for use in non-web applications.
For Use case A :
Instead of DB you can keep the url mappings in a property file and then use property place holder to initialize beans using xml configuration on context up. This way remaining inside the spring framework, you can avoid annotations.
For Use Case B :
Tomcat supports dynamic reloading of classes but that to of only non structural changes in class file. But this has memory leaks as well as it doesnt cleans up old instance of class loader rather it creates a new instance.
Its quite achievable using spring-mvc-router API.
Please check below link
url-action mapping & routing in Spring MVC 3.0
Here the URL can be configured to controller.method using .conf file, but this can be achievable using java configuration, and i haven't tried so far.
Also if xml configuration chosen, then check out the property 'autoReloadEnabled', but its not adviceable for production use.
Hope this helps!!!

Using GSP views in plain Spring MVC without Grails

I would like to use GSP views instead of JSP/JSTL views in a plain old Spring MVC application. I have added a groovy.servlet.TemplateServlet to web.xml like this:
<servlet>
<servlet-name>GroovyTemplate</servlet-name>
<servlet-class>groovy.servlet.TemplateServlet</servlet-class>
<init-param>
<param-name>template.engine</param-name>
<param-value>groovy.text.GStringTemplateEngine</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>GroovyTemplate</servlet-name>
<url-pattern>*.gsp</url-pattern>
</servlet-mapping>
And setup a Spring InternalResourceViewResolver to load the GPS files. Upto this point it all works fine, but to expose the values in the Model to the template I had to do some tricks (subclassing TemplateServlet and adding them to the ServletBinding).
Now my next obstacle is that JSTL by default escapes XML when using the c:out tag and Grails has the notion of codecs to automatically escape values used in a GSP. The template method described above does not escape by default, which requires the developers to be very careful to avoid XSS vulnerabilities.
Is there another (better) way to use GSP including automatic escaping in a plain Spring MVC application without using Grails?
Today GSP for Spring Boot was just released. This provides the ability to use GSP instead of JSP in a regular Spring web application. You can see an example here: https://github.com/grails/grails-boot/blob/master/sample-apps/gsp/script/templates/index.gsp
Instead of using a TemplateServlet, you could have also used a GroovyPagesServlet for that purpose (I haven't tested that, just looked at Grails' web.xml and the class' code).
The latter requires a Spring bean to be setup, named groovyPagesTemplateEngine, and typed GroovyPagesTemplateEngine (GStringTemplateEngine in this case).
Configuring the view layer with an InternalResourceViewResolver is correct. You'll have assigned a GroovyPageView.
GSPs, by default, are not configured to perform HTML output escaping. To configure that, change grails.views.default.codec from none to html in Config.groovy. See this article for more information.
We have extracted GSP from Grails, customized it for Spring MVC applications and improved configuration support. Please see our tool Rabbtor. We don't provide it open source, but usage is free of charge and we have been using it in our own applications. GSP for Spring Boot depends on Spring boot, it is not maintained and some tag libraries depend on Grails. We removed these dependencies, created our own custom tag libraries which better suit Spring MVC apps.Most tag libraries are supported and have similar implemantations to Spring JSP tags.A data-bound form tag library is provided and also you can register your tag libs or packages.

Using pure servlets (Java Servlet, no framework) in a project using the Spring framework?

We've got some Pure Servlets (pure Java classes following the Servlet API, no framework) that we'd like to include in a project that relies heavily on the Spring Framework.
What's the best way of including these servlets in the project, when all the new code we're writing is making heavy use of Spring 3 features?
your servlet container can run multiple servlets, spring is just one of them. why not just include your servlets in the web.xml and see if it works? it should work. spring is not that intrusive, yet (but obviously it already intruded the minds of many developers)
If you declare servlets in the web.xml, alongside the Spring front controller, it most certainly will work.
You just have to be careful when you declare which URLs map to the servlets. If you send "/*" to the Spring front controller, none of your requests will reach your other servlets. Be specific about what you need to send to each one.
As you might know, servlets cannot be configured as Spring beans. If your question is about colloborating with spring beans from a servlet, do refer this thread and also this
Spring provides a couple of classes to make this bridging easier.
ServletForwardingController
Spring Controller implementation that
forwards to a named servlet, i.e. the
"servlet-name" in web.xml rather than
a URL path mapping. A target servlet
doesn't even need a "servlet-mapping"
in web.xml in the first place: A
"servlet" declaration is sufficient.
Useful to invoke an existing servlet
via Spring's dispatching
infrastructure, for example to apply
Spring HandlerInterceptors to its
requests.
ServletWrappingController
Spring Controller implementation that
wraps a servlet instance which it
manages internally. Such a wrapped
servlet is not known outside of this
controller; its entire lifecycle is
covered here (in contrast to
ServletForwardingController).

Spring MVC REST : static files unaccessible because of url-pattern

My Spring Dispatcher servlet url-pattern is /* (as spring MVC REST suggests)
Now all the request are resolved by this Servlet. even CSS/JS/Images also get resolved and handled by servlet..
So, Spring MVC tries to find controller.. :(
How to bypass this? Is there any standard way out of this problem??
& Don't want to change url-pattern to /rest/* (so, other static resources get accessed by /css/ or /js etc.)
You can map your controllers to a smaller set of URLS (i.e. /app/*), and then rewrite the URLs that your users actually see so that they don't even know about. Have a look at the mvc-basic webapp sample, particularly web.xml and urlrewrite.xml to see how this is done.
Map the Spring dispatcher to some subsection of the URL space, and use Tuckey to rewrite URLs the user deals with.
http://www.example.org/app/controller/action -> http://www.example.org/controller/action
Just a heads-up update on this: the default rewrite configuration as defined in the Spring sample did not work out of the box for me. The rewrite rules for stylesheets, scripts, etc. were still processed to the /app/* rule, and subsequently handled by the DispatchServlet, which is not desirable.
I had to add the last="true" attribute to the styles/scripts/images rules to indicate that other rules should not apply, and I had to use the FreeMarker Spring URL macro in any CSS/JS include paths.
Just in case someone encounters the same problem.

Categories