how to specify welcome-file-list in WebApplicationInitializer.onStartup() - spring

Currently I have a web application where we are using web.xml to configure the application. The web.xml has welcome-file-list.
<web-app>
...
<welcome-file-list>
<welcome-file>home.html</welcome-file>
</welcome-file-list>
</web-app>
We are planning to use spring framework and use java class for application configuration.
class MyApplication extends WebApplicationInitializer {
public void onStartUp(ServletContext context){
...
}
}
How do I specify welcome-file-list in this java class?

While developing Spring MVC application with pure Java Based Configuration, we can set the home page by making our application configuration class extending the WebMvcConfigurerAdapter class and override the addViewControllers method where we can set the default home page as described below.
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = { "com.myapp.controllers" })
public class ApplicationConfig extends WebMvcConfigurerAdapter {
#Bean
public InternalResourceViewResolver getViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("home");
}
}
It returns home.jsp view which can be served as home page. No need to create a custom controller logic to return the home page view.
The JavaDoc for addViewControllers method says -
Configure simple automated controllers pre-configured with the
response status code and/or a view to render the response body. This
is useful in cases where there is no need for custom controller logic
-- e.g. render a home page, perform simple site URL redirects, return a 404 status with HTML content, a 204 with no content, and more.
2nd way - For static HTML file home page we can use the code below in our configuration class. It will return index.html as a home page -
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/index.html");
}
3rd way - The request mapping "/" below will also return home view which can be served as a home page for an app. But the above ways are recommended.
#Controller
public class UserController {
#RequestMapping(value = { "/" })
public String homePage() {
return "home";
}
}

You can't
As specified in Java Doc
public interface WebApplicationInitializer
Interface to be implemented
in Servlet 3.0+ environments in order to configure the ServletContext
programmatically -- as opposed to (or possibly in conjunction with)
the traditional web.xml-based approach.
but you still need minimal configuration in web.xml , such as for
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

#EnableWebMvc
#Configuration
#ComponentScan("com.springapp.mvc")
public class MvcConfig extends WebMvcConfigurerAdapter {
...
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/*.html").addResourceLocations("/WEB-INF/pages/");
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/index.html");
}
...
}
This might help.

this works for me...
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/index.html");
}

Related

How to allow websocket|sockjs path 'socket.do/info' when Spring MVC url-pattern mapping is "*.do"

I want to open a websocket connection in my Spring MVC apllication, using SockJS,STOMP. The problem I have is similar to this question. but answer will not work for me. I have followed tutorials from here.
As said here my app is returning a 404 to the browser when calling the webapp/socket.do mapping. javascript code is as below :
socket = new SockJS('webapp/socket.do');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {...
My servlet mapping in web.xml file is as below:
`<servlet-mapping>
<servlet-name>dispatch-servlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>`
Now I tried changing url mapping from "*.do" to "/" and using other resource url patterns as suggested here by #Gofier this ("/")made a connection open but not render some resources properly.(webpages dont load properly).
Is there any way I can still use "*.do" and allow a websocket connection with "/info" at the same time ?? Please suggest any possible ways to fix this issue. Thanks.
Update: Showing controller code and config file
#Configuration
#EnableScheduling
#EnableWebMvc
#ComponentScan(basePackages="com.package")
#EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/socket.do").withSockJS();
}
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/queue/", "/topic/");
registry.setApplicationDestinationPrefixes("/app");
}
}
Controller code:
#MessageMapping("/hello")
#SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws Exception {
Thread.sleep(3000); // simulated delay
return new Greeting("Hello, " + message.getName() + "!");
}
How about...
<servlet-mapping>
<servlet-name>dispatch-servlet</servlet-name>
<url-pattern>*.do</url-pattern>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
this?

How to Configure Servlet Mapping and Resource Handler in Spring MVC

I have created sample Spring MVC REST Maven project with following folder structure
ResourceHandlerRegistry configuration as follows
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.raju.spring_app")
public class RootConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static_res/*").addResourceLocations("/WEB-INF/html/static_res/");
}
//Other methods
}
Servlet mapping as follows
public class HelloWorldInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected String[] getServletMappings() {
return new String[] { "/", "/static_res/*" };
}
//Other Methods
}
The problem is whenever I tried to access resource
http://localhost:8080/spring4_rest_angular_demo/static/css/app.css
I got 404 error.
I want to keep this folder structure to get css IntelliSense suggestions
in index.jsp file.
<link href="static_res/css/app.css" rel="stylesheet"></link>
Few corrections :
Replace
return new String[] { "/", "/static_res/*" };
with
return new String[] { "/" };
and
registry.addResourceHandler("/static_res/*")
with
registry.addResourceHandler("/static_res/**")
Also, the right path is
http://localhost:8080/spring4_rest_angular_demo/static_res/css/app.css
and not
http://localhost:8080/spring4_rest_angular_demo/static/css/app.css
With Spring 3.0.4.RELEASE and higher you can use
<mvc:resources mapping="/resources/**" location="/public-resources/"/>
As seen in http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-static-resources
Also, you should avoid putting pages in WEB-INF. Put the folder with html/css/js higher in hierarchy, under the web app folder. Generally, in WEB-INF there should be only configuration xml files.

Spring Boot url mappings order for controllers and static pages

I have a Spring Boot web application which is meant to serve both static and controller based (ModelAndView) pages. Problem is that a controller can serve something like /{string} and a static page must be served with /test.
The problem is that the controller mapping takes precedence, and I need to avoid that. If the user hits /test, he must be forwarded to the test.html static page.
I tried to use the order property of ViewControllerRegistry in this way, with no success:
#Configuration
public class MyWebMvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/test").setViewName("forward:/test.html");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE); // but I tried with 0 and -1 as well: annotated controllers should have order equals to 0
}
}
This is my SpringBootApplication class:
#SpringBootApplication
public class VipApplication {
public static void main(String[] args) {
SpringApplication.run(VipApplication.class, args);
}
}
And this is the controller code:
#Controller
public class VipController {
#RequestMapping(value = "/{string}")
public ModelAndView vip(#PathVariable("string") String string) {
ModelAndView mv = new ModelAndView("mypage");
return mv;
}
}
How can I reorder the mappings to make sure static pages are considered before annotated controllers?
(I'm not sure, but) I suggest to override WebMvcConfigurerAdapter.addResourceHandlers() method and configure order of resource handler by invoking ResourceHandlerRegistry.setOrder()

Spring MVC TrailingSlash matching

I am using Spring MVC 4.1, and this is the core config:
#EnableWebMvc
#Configuration
#ComponentScan(basePackages = {""})
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(true);
configurer.setUseTrailingSlashMatch(false);
}
....
}
#Controller
#RequestMapping("/api/deps")
public class DepartmentCtrl {
#RequestMapping(value = "", method = RequestMethod.GET)
public Result index() {
return ...;
}
}
While when I open this the url:
/context/api/deps
I will get the result as expected, however once I will get a 404 once I visit the link:
/context/api/deps/
As shown, I have config the PathMatchConfigurer by setUseTrailingSlashMatch(false) , but it seems that it does not work.
Is there anything wrong in my configuration?
use this:
setUseTrailingSlashMatch(true)
According to javadoc, setUseTrailingSlashMatch determines:
Whether to match to URLs irrespective of the presence of a trailing
slash. If enabled a method mapped to "/users" also matches to
"/users/".
Honestly, there is no need for this piece of configuration, since its enabled by default and you by passing false to it, disabled it.
What happens when you pass "/" in the value attribute of RequestMapping Annotation?

Spring serving static content while having wildcard controller route

My application is build using backbone on frontend and spring framework on backend. It is a single html application. Routes are handled by backbone, so I have a backend route with the next structure:
#RequestMapping(value="/**", method=RequestMethod.GET)
public String Pages()
{
return "index";
}
To point everything to my index.html. The thing is that the static content
files are pointed to this route too, and I don't want this. I've tried to
config WebMvcConfigurerAdapter by overriding addResourceHandler method for
static content, but it doesn't work.
#Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/js/**").addResourceLocations("/resources/js");
}
}
How can I point every route to my index.html except /js/** and /assets/** ?
Thank you
The first thing is that your controller method that's mapped to /** will be taking priority over any resource requests. You can address this by increasing the precedence of ResourceHandlerRegistry. Add a call to registry.setOrder(Ordered.HIGHEST_PRECEDENCE) in the addResourceHandlers method of StaticResourceConfiguration:
#Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
registry.addResourceHandler("/js/**").addResourceLocations("/resources/js");
}
}
The second thing is that, by default, Spring Boot configures two resource handlers for you by default, one mapped to /** and one mapped to /webjars/**. Due to the change described above, this will now take priority over the method in your controller that's also mapped to /**. To overcome this, you should turn off default resource handling via a setting in application.properties:
spring.resources.addMappings=false

Resources