Custom path resolving static resources Spring - java

I am working on Spring Boot application. The general problem is the following: I've created REST API, a few controllers. However, I also have some static HTML files, located in "resources/static".
What I want to achieve, is to configure Spring resolvers so that I could access static content without appending ".html". On practise, I expect to access static HTML by path "ip:port/htmlPage" instead of "ip:port/htmlPage.html"
However, I don't want to create methods like this one:
#Controller
public class ViewMaster {
#RequestMapping("/home")
public String home() {
return "home";
}
So, properties like
spring.mvc.view.suffix=.html
not working for me. Any possibilities to avoid creation per page endpoint in a controller?

After reading your question i have tried a lot but unable to serve html from static folder without extention. What works for me is to create an #RequestMapping like this:
#RequestMapping(value="/static/{htmlName}")
String getStaticHtml(#PathVariable String htmlName){
return htmlName;
}
And moved html files to templates folder. So there is no need to create different end points to access html pages, just pass the name of html without extention and this will do the trick

Related

How to access HTML files **through a controller** in Spring boot without a template engine

So I have been trying hard to get a simple app to run with populating an HTML file through a controller without using a template engine.
I thought I would take some time to post about my findings related to the subject above. See answer below
Soo the question here is How to access HTML files through a controller in Spring boot without a template engine?
This is a very simplistic answer to a simple issue, this is not meant to scale and does not take into account the entirety of your project
Please keep in mind this is not the norm in a business environment but it was really bothering me how I cannot get a simple HTML to populate from a controller without using a template engine. I got it to work with thymeleaf dependency but I wanted to just get it to work as bare bones as possible. I read a lot of posts with ViewResolver Config classes or things a like but nothing worked. It would conflict with the internal resolvers of Spring boot.
Simple answer is once spring boot is initialized...all your static files must be in resources/static/
Templates folder is specific to use for Thymeleaf, based on my findings and it wont work if you just put it in the resource folders.
With your files in resources/static/ you can access it by going to localhost:8080/yourfilename.html
But if you want to access it through a controller you create a controller with the following:
#Controller
public class IndexController {
#RequestMapping("/")
public String getIndex(){
return " index.html";
}
}
If you want to remove the .html in your return value then you must add the following to your application.properties file
spring.mvc.view.suffix=.html
Then you can use the following
#Controller
public class IndexController {
#RequestMapping("/")
public String getIndex(){
return " index";
}
}
Once again this is a simple research I did on my own just to get it to work.

How to display URL link different than page JPS page?

I am not sure it this is possible at all. I see that in Facebook when you crate a business page you will get a link with page number, for example:
https://www.facebook.com/degendaUK/
I would like to know if it is possible to create a link like that without having an HTML or JSP page called "DegendaUK" for example.
In my code I have page
http://localhost:8080/offers/empresa?get_Business_ID=29-11-2017-03:39:22R7M5NZ8ZAL
The standard page is called "Empresa" and then I pass the ID so I can query the database.
Is there anyway that instead of my URL I would get
http://localhost:8080/offers/BUSINESS-NAME
without creating a JSP page for each business?
I am using Spring MVC.
You may use Spring #Controller, #RequestMapping and #PathVariable annotations to do this.
#Controller
public class Controller
{
#RequestMapping(value = "/offers/{id}")
public String offer(#PathVariable String id, final Model model)
{
//pass the value from the url to your jsp-view, access it via ${id} from
//there
model.add("id",id);
//render the page "empressa.jsp"
return "empressa";
}
}
Hint: You may need some and in your XML config to make those annotations work.
If your using spring-boot, this should be preconfigured already an work out of the box.
Don't forget to secure those things if they're not public things using spring-security :)

Load multiple Angular projects from Spring boot

I have a Spring boot application and I have two completely independent angular projects.
One project for the end user and another project for the admin.
For business reasons, I am forced to have both of them as two different projects. I want both these projects to be packaged into the same WAR and when the user hits the URL for the end user, the end user angular application should be loaded and when the admin URL is accessed, the admin angular project should be loaded.
I know that Spring boot loads the angular project from /public or /static directories. However, since in my case, I have two different projects, I cant put them under the same folder since both of them have many file names in common including index.html.
So far, I have done the following:
Created two different folders under "public" as "enduser" and
"manage".
Created a controller which has two methods :
#Controller
public class SampleController {
#RequestMapping(method = RequestMethod.GET, produces = "text/html", value
= "/enduser")
public String enduser() {
return "/enduser/index.html";
}
#RequestMapping(method = RequestMethod.GET, produces = "text/html", value
= "/admin")
public String admin() {
return "/admin/index.html";
}
}
However, when I do like this only the index.html file is loaded and the other components are not loaded(by which I mean the entire angular project is not loaded). So the dependent views and styles etc are not loaded.
Does anybody have an idea on how to handle the above scenario? Thanks.
Just posting the solution below it might help somebody else.
I am using two different folder where I am placing the contents of dist folder from angular source code.
I have two different angular based applications admin and public.
Locations in spring app where I am placing the compiled angular code is as:
/src/main/resources/admin-app/*
(admin-index.html and other static
files from admin angluar project)
/src/main/resources/static/*
(index.html and other static files from public angluar project)
Spring boot config
#EnableAutoConfiguration
public class AddCustomLocations {
#Bean
WebMvcConfigurer configurer () {
return new WebMvcConfigurerAdapter() {
#Override
public void addResourceHandlers (ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pages/**").
addResourceLocations("classpath:/admin-app/");
}
};
}
That's it now when you will hit http://localhost:8080. It will load the public angular app.
And when you will hit
Now when I am trying to open http://localhost:8080/pages/admin-index.html
It will load the admin angular app.
The magic is all files inside static folder will work by default but if we want to create another folder for placing our static files. We will have to notify the spring boot app.
You can also create a sub folder inside the static folder.
public & admin-app
You will have to hit the url like this
localhost:8080/public/index.html
localhost:8080/public/admin-index.html
You will not need to create the above spring configuration for this.
Resolved it the following way:
Created an MVC controller, added two different methods for each URL pattern.Copied the dist files of each project into a a separate folder under static folder.Added a different tag to each project.This way your angular project wont work on grunt serve.So you will have to set url as empty when you run on grunt serve and set it to a value only when you run for build.

Serve images outside web application

I want to access static files, which are outside my web application in a known directory. I have read many options over the www, but I have still some questions about this.
Basically I want to declare a context for the defaultservlet of my application server. In my case I'm trying with the Tapestry Tutorial, which is a Maven based project and imported to eclipse.
The idea was to create a httpservlet, which gets the file from the location. Do someone of you know where I can grab an example of such a servlet and how I can call him? I know that the servlet must be probably declared as a service, because all pages of the application need to access the files, but I could also be mistaken and it is enough to import it, let say, in the layout page (All pages use the layout.tml file). I basically don't have any clue how to do it with a servlet. Can someone show me the light?
Tank you very much.
Another simpler solution is to create a page which returns a stream response
public class StaticFile {
StreamResponse onActivate(String fileName) {
return new StaticFileStreamResponse(fileName);
}
}
Then in another component / page
#Inject ComponentResources resources;
public Link getStaticFileLink() {
return resources.createPageRenderLinkWithContext("StaticFile", "path/to/myFile.jpg");
}
TML
<img src="${StaticFileLink}" />
But then you won't take advantage of tapestry's 304 NOT_MODIFIED response as in my other solution.
The tapestry way of doing this is by contributing an AssetRequestHandler and an AssetFactory.
AppModule.java
public static void contributeAssetDispatcher(
MappedConfiguration<String, AssetRequestHandler> config,
ResourceStreamer streamer)
{
config.add("staticfile", new StaticFileAssetRequestHandler(streamer));
}
public void contributeAssetSource(
MappedConfiguration<String, AssetFactory> config)
{
config.add("staticfile", new StaticFileAssetFactory());
}
Then in your tml you can use
<img src="${asset:staticfile:path/to/myFile.jpg}" />
Take a look at the ContextAssetRequestHandler, ClasspathAssetRequestHandler, ContextAssetFactory and ClasspathAssetFactory for inspiration.
Be careful not to open up a security hole where a hacker can access any file on your server by passing file paths prefixed with ../../

spring mvc 3.0: put a bunch of .jsp files under spring's control

In my spring mvc 3.0 project I have a directory full of .jsp files (~150) which I want to put under spring's control.
Until now they where invoked by web.xml directly, without going thru the spring servlet.
From now, I want to put them all under spring's control to enjoy spring's goodies and make my project more uniform.
Of course, I don't want to write a single controller for each .jsp file. How can I do this?
In the case of a single JSP page you can use <mvc:view-controller>.
When you have many pages, you can write a catch-all controller like this:
#RequestMapping("/folder/{name}.jsp")
public ModelAndView catchAll(#PathVariable String viewName) {
return new ModelAndView("legacy/" + viewName);
}
However, it may conflict with JSP processing servlet. If so, you need to apply some URL rewriting filter.
JSPs must not include any code that requires dependency injection. So don't do it.
If you really must, you can use
<%!
public void init() {
ApplicationContextUtils.getRequiredWebApplicationContext(
getServletContext()).getAutowireCapableBeanFactory()
.autowireBean(this);
}
%>
But this is extremely ugly.

Categories