Spring Boot + JSF static page configurations - spring

am getting started with Spring Boot + JSF.
Spring documentation says:
Spring will automatically load and serve resources inside
/static (or /public or /resources or /META-INF/resources.
This is not working for me.
it is discouraged to use the "webapp" (src/main/webapp) folder.
But for my static content, it seem to be the only folder thats working with my JSF static page.
see Spring Boot static content.
I have tried these configuration:
#Configuration
public class JSFServletConfigs implements ServletContextInitializer// ,ServletContextAware
{
#Override // ServletContext initiallization parameters
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.setInitParameter("facelets.DEVELOPMENT", "false");
servletContext.setInitParameter("javax.faces.PROJECT_STAGE", "Development");
servletContext.setInitParameter("javax.faces.DEFAULT_SUFFIX", ".xhtml");
servletContext.setInitParameter("javax.faces.PARTIAL_STATE_SAVING_METHOD", "true");
servletContext.setInitParameter("javax.faces.FACELETS_REFRESH_PERIOD", "-1");
}
#Bean // Registering the FacesServlet.
public ServletRegistrationBean servletRegistrationBean() {
FacesServlet servlet = new FacesServlet();
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(servlet) {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
FacesInitializer facesInitializer = new FacesInitializer();
Set<Class<?>> clazz = new HashSet<Class<?>>();
clazz.add(JSFServletConfigs.class);
facesInitializer.onStartup(clazz, servletContext);
}
};
servletRegistrationBean.addUrlMappings("*.xhtml", "*.jsf", "*.html");
return servletRegistrationBean;
}
#Bean
public InternalResourceViewResolver jsfViewResolving(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/<sub-folder of any LOCATION>/");
viewResolver.setSuffix(".xhtml");
return viewResolver;
}
}
Servlet pre-configs:
#Configuration
#EnableWebMvc
public class DefaultServletConfigs extends WebMvcConfigurerAdapter {
#Override // Enabling the default Servlet at path="/"
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
private final String[] LOCATIONS = {"<All my possible locations>"};
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if(!registry.hasMappingForPattern("/**")){
registry.addResourceHandler("/**").addResourceLocations(LOCATIONS);
}
if(!registry.hasMappingForPattern("webjars")){
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
}
My Question are:
What am I missing here?
How do I get the flexibility to place my resources in any of the other folders above
(i.e. "/static", "/public", "/resources", "/META-INF/resources").

Related

How to config MessageDispatcherServlet and ServletRegistration both by using spring annotaion

I have configure MessageDispatcherServlet for soap services and ServletRegistration for web services but controller not call in case of web services.
public class WebAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
// use MessageDispatcherServlet instead of standard DispatcherServlet for SOAP messages
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setContextClass(WebServiceWsConfig.class);
servlet.setApplicationContext(context);
servlet.setTransformWsdlLocations(true);
// register MessageDispatcherServlet as Web Service entry point
final ServletRegistration.Dynamic dispatcher = servletContext.addServlet("MessageDispatcherServlet",servlet);
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/soapws/*");
dispatcher.addMapping("/");
}
}
My WebServicesConfig class is
#Configuration
#EnableWs
#EnableWebMvc
#ComponentScan(basePackages = "")
#PropertySource(value = {"classpath:config_local.properties"})
public class WebServiceConfig extends WebMvcConfigurerAdapter {
#Autowired
private Environment env;
#Bean(name = "pos")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema posSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("posPort");
wsdl11Definition.setLocationUri("/soapws");
wsdl11Definition.setTargetNamespace("http://---.---.in/soap");
wsdl11Definition.setSchema(posSchema);
return wsdl11Definition;
}
#Bean
public XsdSchema studentsSchema() {
return new SimpleXsdSchema(new ClassPathResource("pos.xsd"));
}
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
I solve my problem using Spring Boot configuration, This help me calling Soap services as well as Web services.
#EnableWs
#Configuration
public class WebServiceConfig extends WsConfigurerAdapter{
#Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
#Bean(name = "pos")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema posSchema)
{
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("posPort");
wsdl11Definition.setLocationUri("/soapws");
wsdl11Definition.setTargetNamespace("http://---.---.in/soap");
wsdl11Definition.setSchema(posSchema);
return wsdl11Definition;
}
#Bean
public XsdSchema studentsSchema() {
return new SimpleXsdSchema(new ClassPathResource("pos.xsd"));
}

Spring static resource mapping does not work

i am trying to create a Spring MVC application with security included. All configuration is made in code, no XML-s. First, i have my WebApplicationInitializer, mapping all requests to my dispatchservlet:
public class DBCAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(DBCConfiguration.class);
ctx.setServletContext(servletContext);
ServletRegistration.Dynamic servlet = servletContext.addServlet(
"dispatcher", new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
servlet.setMultipartConfig(new MultipartConfigElement("", 1024*1024*5, 1024*1024*5*5, 1024*1024));
}
Also there is a config file:
#EnableWebMvc
#Configuration
#ComponentScan(basePackages = "our.dbc")
public class DBCConfiguration extends WebMvcConfigurerAdapter {
private static final Logger log = Logger.getLogger(DBCConfiguration.class);
#Bean
public InternalResourceViewResolver getInternalResourceViewResolverJsp(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
viewResolver.setOrder(0);
log.info("#### Internal view resolver 0 called...");
return viewResolver;
}
#Bean
public StandardServletMultipartResolver multipartResolver(){
log.info("#### Multipart resolver called...");
return new StandardServletMultipartResolver();
}
// #Override
// public void addResourceHandlers(final ResourceHandlerRegistry registry) {
// registry.addResourceHandler("/resources/**")
// .addResourceLocations("/resources/");
//
// }
//
// #Override
// public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
// configurer.enable();
// }
}
As you can see, i have tried both addResourceHandler and configureDefaultServletHandling, but none of those worked. Problem is that all request by default, with lowest priority end up returing welcome page (so if bad address requested, welcome is returned :), so that instead of getting the css client gets back to welcome page:
#Controller
public class FileUploadController {
private static final Logger LOG = Logger.getLogger(FileUploadController.class);
private static final String FORM = "form";
private static final String WELCOME = "welcome";
private static final String DENIED = "accessDenied";
private static final String UPLOADED_REDIRECT = "redirect:/uploaded";
#Autowired
FileUploadService uploadService;
#RequestMapping(value = "/**", method = RequestMethod.GET)
public String getWelcome() {
return WELCOME;
}
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String loginPage() {
LOG.info("#### /login called..." );
return "login";
}
#RequestMapping(value = { "/uploaded" }, method = RequestMethod.GET)
public String getUploaded() {
LOG.info("#### /uploaded called..." );
return "uploaded";
}
.
.
.
As i said, i also have security configured, but with default container servlet serving static resources, it whould not have to be changed. Anyway, i tried also to add permitall to resources, but no success. Anyway if i disable security it does not work either, so security is not the problem.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.antMatchers("/welcome").permitAll()
.antMatchers("/form").access("hasRole('ADMIN')and hasRole('USER')")
.
.
.
But no chances. If i type http://localhost:8080/SpringMVC/resources/app.css instead of getting the stylesheet, browser gets back to welcome page.
Any suggestions? Any help whould be appreciated :)

#ManagedBean not initialize with jsf + spring boot

I am trying to build simple backoffice app. I choose to use jsf(PrimeFaces) because of rich ui components that doesn't require any Front end developer(The look doesn't matter it just to perform actions on our main system).
The issue that i have is that #ManagedBean doesn't work at all.. It just doesn't consider it and does not perform auto scan.
In case i put the bean in faces-config.xml it works.. Anyone has an idea?
The config file is:
#Bean
public FacesServlet facesServlet() {
return new FacesServlet();
}
#Bean
public ServletRegistrationBean facesServletRegistration() {
ServletRegistrationBean registration = new ServletRegistrationBean(facesServlet(), new String[] { "*.xhtml", "*.jsf" });
registration.setName("FacesServlet");
registration.setLoadOnStartup(1);
return registration;
}
#Configuration
static class ConfigureJSFContextParameters implements ServletContextInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", "true");
servletContext.setInitParameter("javax.faces.DEFAULT_SUFFIX", ".xhtml");
servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", Boolean.TRUE.toString());
servletContext.setInitParameter("encoding", "UTF-8");
servletContext.setInitParameter("facelets.SKIP_COMMENTS", Boolean.TRUE.toString());
}
}
#Bean
public ServletListenerRegistrationBean<ConfigureListener> jsfConfigureListener() {
return new ServletListenerRegistrationBean<ConfigureListener>(new ConfigureListener());
}

Spring mvc 4.0.5 long polling example

I'm trying to implement long polling in spring with DefferedResult. I'm trying to follow this example, from spring, https://github.com/rstoyanchev/spring-mvc-chat
I'm following configuration to the letter (almost, see below). When I'm launching it I got:
HTTP Status 500 - Request processing failed; nested exception is java.lang.IllegalStateException: Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "true" to servlet and filter declarations in web.xml.
Which is coming from: StandardServletAsyncWebRequest.
My config classes:
public class MVCInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses () {
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebMvcConfig.class, PresentationConfig.class, SecurityConfig.class, EmailConfig.class };
}
#Override
protected String[] getServletMappings () {
return new String[] { "/" };
}
#Override
protected void customizeRegistration(Dynamic registration) {
registration.setAsyncSupported(true);
}
#Override
protected boolean isAsyncSupported () {
return true;
}
}
#Configuration
#EnableWebMvc
#EnableAsync
#ComponentScan (basePackages = { "com.xxx.presentation" })
public class WebMvcConfig extends WebMvcConfigurerAdapter {
private static final Log log = LogFactory.getLog(WebMvcConfig.class);
#Override
public void configureAsyncSupport (AsyncSupportConfigurer configurer) {
configurer.setDefaultTimeout(30 * 1000L);
}
public void addViewControllers (ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("teledetailer");
}
#Override
public void addResourceHandlers (ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/images/**").addResourceLocations("/images/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
}
#Bean
public ViewResolver viewResolver () {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Override
public void addReturnValueHandlers (List<HandlerMethodReturnValueHandler> returnValueHandlers) {
List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
messageConverters.add(new StringHttpMessageConverter());
messageConverters.add(new MappingJackson2HttpMessageConverter());
returnValueHandlers.add(new RequestResponseBodyMethodProcessor(messageConverters));
super.addReturnValueHandlers(returnValueHandlers);
}
}
I'm using:
Java 7
Tomcat 7.0.54
Spring 4.0.5
Any help would be much appreciated. Really frustrating with lack of decent examples.
p.s. if amount of places where I tried to enable async support seems overwhelming - don't worry I'm just trying to figure out how exactly it should be done.
Thanks, and I hope you can help me.
After asking Rossen Stoyanchev for help (great guy, big thanks to him!) he pointed out that I have springSecurityFilterChain in my web.xml, so this one also needs to be configured for async support:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<async-supported>true</async-supported>
</filter>
Hope it will help the rest of you who has the same problem.

spring boot not launching static web content

Am trying to launch index.html in my spring boot app but see 404. What dependency am I missing?
build.gradle (multi project)
project('sub-project')
{
apply plugin: 'spring-boot'
compile (
"org.springframework.boot:spring-boot-starter-web:1.0.0.RC5",
"org.springframework.boot:spring-boot-starter-actuator:1.0.0.RC5"
.. few more app specific dependencies
)
project structure:
MainProject
-- sub-project
src
main
resources
index.html
Application class:
#Configuration
#EnableAutoConfiguration
class Application {
public static void main(String[] args) {
SpringApplication.run([SpringServlet, Application, "classpath:/META-INF/com/my/package/bootstrap.xml"] as Object[], args)
}
}
**Launching http://localhost:8080/index.html throws 404.**
Found the root cause. Changing the SpringServlet's Url mappings to "Rest" resources specific path fixed it.
Earlier "/*" was also interpreted by SpringServlet and was not able to render the index.html.
class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run([Application, "classpath:/META-INF/com/my/package/mgmt/bootstrap.xml"] as Object[], args)
}
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application);
}
#Bean
ServletRegistrationBean jerseyServlet() {
ServletRegistrationBean registration = new ServletRegistrationBean(new SpringServlet(), "/rest/*");
Map<String, String> params = ["com.sun.jersey.config.property.packages": "com.my.package.mgmt.impl;com.wordnik.swagger.jersey.listing"]
registration.setInitParameters(params)
return registration;
}
#Bean
ServletRegistrationBean jerseyJaxrsConfig() {
ServletRegistrationBean registration = new ServletRegistrationBean(new DefaultJaxrsConfig(), "/api/*");
Map<String, String> params = ["swagger.api.basepath": "http://localhost:8080/api", "api.version": "0.1.0"]
registration.setInitParameters(params)
return registration;
}
#Configuration
public class WebConfig implements WebMvcConfigurer {
/** do not interpret .123 extension as a lotus spreadsheet */
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer)
{
configurer.favorPathExtension(false);
}
/**
./resources/public is not working without this
*/
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/public/");
}
}

Resources