I know that it's popular issue but I research whole stackoverflow and I couldn't find solution for my problem or exisiting solution did not work.
My application uses Spring and Hibernate. Polish letters are changing to questions marks after persist to database.
My code:
SecurityConfig.class
#EnableWebSecurity
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserService userService;
#Override
public void configure(WebSecurity web) throws Exception {
web.debug(false);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceEncoding(true);
http.addFilterBefore(filter,CsrfFilter.class);
System.out.println("Jestem w WebSecurityConfigurerAdapter");
...
}
AppConfig.java
#EnableWebMvc
#Configuration
#ComponentScan({ "com.everydayhabits.*" })
#EnableTransactionManagement
#PropertySource("classpath:persistence-mysql.properties")
#Import({SecurityConfig.class})
public class AppConfig implements WebMvcConfigurer {
...
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
viewResolver.setContentType("text/html;charset=UTF-8");
return viewResolver;
}
SpringMvcInitializer.class
public class SpringMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class, SecurityConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
SpringSecurityInitializer.class
public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
#Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
super.beforeSpringSecurityFilterChain(servletContext);
FilterRegistration.Dynamic characterEncodingFilter;
characterEncodingFilter = servletContext.addFilter("encodingFilter", new CharacterEncodingFilter());
characterEncodingFilter.setInitParameter("encoding", "UTF-8");
characterEncodingFilter.setInitParameter("forceEncoding", "true");
characterEncodingFilter.addMappingForUrlPatterns(null, false, "/*");
}
}
pom.xml
...
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<resourceEncoding>${project.build.sourceEncoding}</resourceEncoding>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
...
Apache server.xml
...
<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8" />
...
myjsppage.jsp
...
<%# page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
...
Has I missed anything to enable UTF-8 to my application? Does anyone has similar problem? Thanks in advance!
Can you try changes to your SpringSecurityInitializer like below:-
#Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
super.beforeSpringSecurityFilterChain(servletContext);
FilterRegistration.Dynamic characterEncodingFilter;
CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
encodingFilter.setEncoding("UTF-8");
encodingFilter.setForceEncoding(true);
characterEncodingFilter = servletContext.addFilter("encodingFilter", encodingFilter);
characterEncodingFilter.addMappingForUrlPatterns(null, false, "/*");
}
Related
I am trying to secure my Spring REST Services with Spring security and OAuth2. I managed to get the tokens:
tokens
But when I try to get an secured rest service I get access denied:
denied
Can anybody tell me why this is happening?
AuthorizationServerConfig:
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
private static String REALM="EXAMPLE_REALM";
#Autowired
private TokenStore tokenStore;
#Autowired
private UserApprovalHandler handler;
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authManager;
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("myRestClient") // client id
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read", "write", "trust")
.secret("{noop}P#ssw0rd")
.accessTokenValiditySeconds(240).//invalid after 4 minutes.
refreshTokenValiditySeconds(600);//refresh after 10 minutes.
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore).userApprovalHandler(handler)
.authenticationManager(authManager);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.realm(REALM+"/client");
}
}
ResourceServerConfig:
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "SPRING_REST_API";
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).stateless(false);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.
anonymous().disable()
.requestMatchers().antMatchers("/api/**")
.and().authorizeRequests()
.antMatchers("/api/**").access("hasRole('ADMIN')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
SecurityConfig:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private ClientDetailsService clientService;
#Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
#Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception{
auth
.inMemoryAuthentication()
.withUser("user")
.password(passwordEncoder().encode("password"))
.roles("USER")
.and()
.withUser("admin")
.password(passwordEncoder().encode("admin"))
.roles("ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/oauth/token").permitAll()
.antMatchers("/about").authenticated();
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
#Bean
#Autowired
public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore){
TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
handler.setTokenStore(tokenStore);
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientService));
handler.setClientDetailsService(clientService);
return handler;
}
#Bean
#Autowired
public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
}
AboutController (rest service):
#RestController
public class AboutController {
#RequestMapping(value = "/about", method = RequestMethod.GET)
public ResponseEntity<?> home() {
return new ResponseEntity<>("This is a demo application to show how to secure REST API using Spring Security and OAuth2", HttpStatus.OK);
}
}
application.properties:
server.servlet.context-path=/api
security.oauth2.resource.filter-order = 3
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>gs-rest-service</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Thanks in advance!
Got this working. My problem was that in the application.config file I added /api so that for all my services an api folder is in place like: http://localhost:8080/api/about .. in my ResourceServerConfig class I added /api/** as requestMatchers and antMatchers.... the sercurity configuration is looking for serverice after this api prefix folder.... so exposing my about rest is done in this way:
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "SPRING_REST_API";
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).stateless(false);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.
anonymous().disable()
.requestMatchers().antMatchers("/about/**")
.and().authorizeRequests()
.antMatchers("/about/**").access("hasRole('ADMIN')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
By the way.. I can request the about service with a parameter like in my request screenshot but it works also if i provide the authorization token als a Bearer Token authorization header....
Regards!
Peter
I am new to java spring framework, and I am trying to call a method or initialize a method on startup so when the application start, I will be able to see my data from the database on my jsp page. I have try #EventListener, #PostConstruct but nothing is working for me.
This is my WebConfigura class
#Configuration
#ComponentScan("com.store.spring")
#EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter {
#Bean
public DataSource dataSource() {
final JndiDataSourceLookup lookup = new JndiDataSourceLookup();
lookup.setResourceRef(true);
DataSource dataSource = lookup.getDataSource("jdbc/product_db");
return dataSource;
}
#Bean
public UrlBasedViewResolver resolver() {
UrlBasedViewResolver viewResolver = new UrlBasedViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
return viewResolver;
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resource/css/**").addResourceLocations("/css/").setCachePeriod(31556926);
}
#Override
public void configureDefaultServletHandling (DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new HeaderInterceptor());
}
}
This is Web Application Initializer class
#Component
public class WebInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(WebConfiguration.class);
// Add context.setCongiglocation("/WEB-INF/spring/dispatcher-config.xml");
ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcher", new DispatcherServlet(context));
registration.addMapping("/");
registration.setLoadOnStartup(1);
ContextLoaderListener listener = new ContextLoaderListener(context);
servletContext.addListener(listener);
}
}
This is the controller class
#Controller
public class ProductController {
#Autowired
private ProductService productService;
#RequestMapping("/index")
public String index(Model model) {
List<Product> listProduct = productService.getPrducts();
model.addAttribute("listProduct", listProduct);
return "index";
}
// Request mapping using SQL tag
#RequestMapping("/location")
public String addLocation(Model model) {
List<Product> listProduct = productService.getPrducts();
model.addAttribute("listProduct", listProduct);
return "location";
}
#RequestMapping("/entry")
public String entry() {
return "Entry";
}
#RequestMapping("/aboutUs")
public String aboutUS() {return "AboutUs";}
#RequestMapping("/deal")
public String deal() {
return "Deal";
}
#RequestMapping("/listProduct")
public String listOrganizationService(Model model) {
List<Product> listProduct = productService.getPrducts();
model.addAttribute("listProduct", listProduct);
return "ListOrganizations";
}
}
This is the header interceptor class
public class HeaderInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
request.setAttribute("title", "We hope you have a scary and fun filled halloween");
String location = request.getParameter("locationName");
if (location != null) {
request.setAttribute("locationName", location);
}
return true;
}
}
This is the method I want to initialize or call on start up. Or at least
some thing close to this
#RequestMapping("/index")
public String index(Model model) {
List<Product> listProduct = productService.getPrducts();
model.addAttribute("listProduct", listProduct);
return "index";
}
I am using index.jsp to call the listProduct to print my data out. Notice that index.jsp is the first jsp that call when the application start. And I want it to ab able to automatic print those data out
<div class="main-container" style="text-align: center">
<c:forEach var="row" items="${listProduct}">
<div class="detail">
<td>ID: <c:out value="${row.id}"></c:out></td>
<br/>
<td>Name: <c:out value="${row.productName}"></c:out></td>
<br/>
<td>Quantity: <c:out value="${row.quantity}"></c:out></td>
<br/>
<td>Price: <c:out value="${row.price}"></c:out></td>
<br/>
<td><div class="few-line"><c:out value="${row.description}"></c:out></div></td>
</div>
</c:forEach>
I hope someone could help me out.
For Example I had this code inside my WebInitializer class, and when I run it I got an error message
#EventListener(ContextRefreshedEvent.class)
public void contextRefreshedEvent(Model model) {
List<Product> productList = productService.getPrducts();
model.addAttribute("productList", productList)
}
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:256)
... 56 more
org.apache.catalina.core.StandardContext.startInternal One or more
listeners failed to start.
org.apache.catalina.core.StandardContext.startInternal Context []
startup failed due to previous errors
org.springframework.web.context.support.AnnotationConfigWebApplicationContext.doClose
Closing Root WebApplicationContext: startup date [Sun Aug 13 10:43:51
EDT 2017]; root of context hierarchy
These are my plug and dependencies for my jar
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/jstl/jstl -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
Java Spring initialize, call a method on startup
You can annotate a Spring bean's method with #PostConstruct to have Spring call it after it gets constructed. You can also annotate a method with #Autowired to have Spring call it during the construction of that bean. We typically use one of those to call a method on startup, for example to load data from a database into cache.
I'm trying to set up Thymeleaf in my Spring MVC application but somethings goes wrong
Here is my pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<spring.version>4.3.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring3</artifactId>
<version>3.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>3.0.1.RELEASE</version>
</dependency>
</dependencies>
</project>
and here is my configuration
package thyme.leaf.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
#Configuration
#EnableWebMvc
#ComponentScan("my.package")
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine);
return viewResolver;
}
#Bean
public SpringTemplateEngine templateEngine(TemplateResolver templateResolver) {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
return templateEngine;
}
#Bean
public TemplateResolver templateResolver() {
TemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
return templateResolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
the problem is somewhere with TemplateResolver class in my methods. Unfortunatelly it can not be found at all. I inspected org.thymeleaf.templateresolver package where I think it should be but it is not there
can anybody advice what is wrong here please
Finally found correct implementation:
public class WebConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware {
private ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
#Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
#Bean
public TemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setEnableSpringELCompiler(true);
engine.setTemplateResolver(templateResolver());
return engine;
}
private ITemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("/WEB-INF/templates/");
resolver.setTemplateMode(TemplateMode.HTML);
return resolver;
}
}
I'm not sure but try to change #ComponentScan("my.package") with #ComponentScan("thyme.leaf.config").
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>mavenproject1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>mavenproject1</name>
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.5.RELEASE</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
This is the controller class
#Controller
public class LoginController {
#RequestMapping(value = {"/"},method = RequestMethod.GET)
public ModelAndView showFirstPage(){
System.out.println("Hi Hello mallesh How are you..");
ModelAndView model=new ModelAndView();
model.setViewName("welcome");
return model;
}
}
This is the configuration class
#EnableWebMvc
#Configuration
#ComponentScan({"com.mycomany.mavenproject1.*"})
public class LoginApplicationConfig {
#Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver viewResolver=new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
This is the webApplicationInitializer class
public class WebAppApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { LoginApplicationConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
This is my welcome.jsp class
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8">
<title>JSP Page</title>
</head>
<body>
<h1>Welcome To My Project...</h1>
</body>
</html>
it not show the welcome.page as first page whenever i run my project it shows resource not found
You Can Add the following code in the web.xml file.
<welcome-file-list>
<welcome-file>welcome.jsp</welcome-file>
</welcome-file-list>
In addition to previous answer of Sachin Aryal, You can add more number of welcome pages.
<welcome-file-list>
<welcome-file>welcome.jsp</welcome-file>
<welcome-file>firstpage.html</welcome-file>
<welcome-file>first.jsp</welcome-file>
</welcome-file-list>
The first available file will be taken as welcome file
As i can see you are using Javaconfig i.e no xml approach. I will advice you do it like this
1) Create a root config class, i.e
#Configuration
#ComponentScan({ "com.myrootpackage.whatsoever" })
public class RootClass{
}
2) Make the Class you already have i.e LoginApplication config to extend WebMvcConfigurerAdapter, this will enable you to also load resources or any folders that might have any css or js that you might need in the future
Class LoginApplication extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
//your view resolver bean as you already have above goes here.
}}
3) Now in the webApplicationInitializer class that you already have, take note of the following
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { RootClass.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return class[]{LoginApplication.class];
}
lastly make sure when this application is running you should have Locahlhost:yourport and nothing else to be able to see the welcome.jsp page and make sure welcome.jsp page is located in WEB-INF/views. Hope this helps.
I am using Spring 4, Servlet 3 API and Tomcat 8 for my project. I have a problem with deployment. I am trying to deploy WAR package in my VPS. I am using Intellij IDEA.
I coppied my WAR to /opt/tomcat/webapps path. I can see WAR from Tomcat's apps page. But when I try to browse URL I get 404 Not Found error.
I am using Spring with annotation and empty web.xml and also I am using Spring Security.
WepAppInitializer.java
public class WepAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(final ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(WebConfig.class);
ctx.setServletContext(servletContext);
ServletRegistration.Dynamic dynamic = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
dynamic.addMapping("/acentecilik");
dynamic.setLoadOnStartup(1);
}
}
WebConfig.java
#Configuration
#EnableWebMvc
#EnableTransactionManagement
#ComponentScan("com.decimatech.acentecilik")
#PropertySource("classpath:application.properties")
public class WebConfig extends WebMvcConfigurerAdapter{
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new ThymeleafLayoutInterceptor());
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/resources/**").addResourceLocations("/static/");
}
#Bean
#Description("Thymeleaf template resolver serving HTML 5")
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/html/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("LEGACYHTML5");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setCacheable(false);
return templateResolver;
}
#Bean
#Description("Thymeleaf template engine with Spring integration")
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
return templateEngine;
}
#Bean
#Description("Thymeleaf view resolver")
public ThymeleafViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setContentType("text/html;charset=UTF-8");
viewResolver.setCharacterEncoding("utf-8");
return viewResolver;
}
#Value("${spring.datasource.driver-class-name}")
private String driverClassName;
#Value("${spring.datasource.url}")
private String datasourceUrl;
#Value("${spring.datasource.username}")
private String datasourceUsername;
#Value("${spring.datasource.password}")
private String datasourcePassword;
#Bean(name = "dataSource")
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(datasourceUrl);
dataSource.setUsername(datasourceUsername);
dataSource.setPassword(datasourcePassword);
return dataSource;
}
#Autowired
#Bean(name = "transactionManager")
public HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory);
return transactionManager;
}
#Autowired
#Bean(name = "sessionFactory")
public SessionFactory getSessionFactory(DataSource dataSource) {
LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);
sessionBuilder.scanPackages("com.decimatech.acentecilik.model");
sessionBuilder.addProperties(getHibernateProperties());
return sessionBuilder.buildSessionFactory();
}
private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
properties.put("hibernate.hbm2ddl.auto", "update");
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.format_sql", "true");
properties.put("hibernate.use_sql_comments", "true");
properties.put("hibernate.enable_lazy_load_no_trans", "true");
return properties;
}
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="true">
<display-name>Acentecilik</display-name>
<description>
Acentecilik
</description>
</web-app>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.decimatech</groupId>
<artifactId>acentecilik</artifactId>
<version>1.0-SNAPSHOT</version>
//Some package dependencies
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
Here is some screenshot about what settings I used.
IDEA WAR Settings
Project Structures
Tomcat Manage Apps Page
And 404 Error
How can I solve this problem?
Here is my catalina log file's output. I changed WAR's ownership from root to tomcat user. But still same problem.
02-Oct-2015 16:03:23.800 SEVERE [localhost-startStop-10] org.apache.catalina.startup.ContextConfig.beforeStart Exception fixing docBase for context [/acentecilik]
java.io.IOException: Unable to create the directory [/opt/tomcat/webapps/acentecilik]
at org.apache.catalina.startup.ExpandWar.expand(ExpandWar.java:115)
at org.apache.catalina.startup.ContextConfig.fixDocBase(ContextConfig.java:618)
at org.apache.catalina.startup.ContextConfig.beforeStart(ContextConfig.java:744)
at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:307)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:95)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:402)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:945)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1798)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
02-Oct-2015 16:03:58.561 INFO [localhost-startStop-10] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
02-Oct-2015 16:03:58.649 INFO [localhost-startStop-10] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive /opt/tomcat/webapps/acentecilik.war has finished in 34,860 ms
Edit
I changed /opt/tomcat/webapps ownership to tomcat and now I don't get the 404 error. But now I have this.
INFO [http-nio-8080-exec-17] org.apache.catalina.core.ApplicationContext.log No Spring WebApplicationInitializer types detected on classpath
the exception says
org.apache.catalina.startup.ContextConfig.beforeStart Exception fixing docBase for context [/acentecilik] java.io.IOException: Unable to create the directory
and you've already stated that tomcat is under /opt. so I suppose tomcat has not sufficient permission to create (write permission) on its own directory /opt/tomcat.
If you give write permission to the user who launches the tomcat (most probably your own user) then the problem goes away.
sudo chmod -R 0744 /opt/tomcat