Sunday, 8 April 2018

Spring Web MVC Example from scratch and annotation

Hi
In this post I will create simple web mvc maven project in eclipse. Here I am using only java classes as configuration files(no xml file for configuration).

I m using:
Java 8
Maven 3.3.9
Tomcat 8.5
Windows 8.1, 64 bit
IDE:  Spring Tool Suite
          Version: 3.8.2.RELEASE
          Platform: Eclipse Neon.1 (4.6.1)


Hope u have all setup for java and maven.

I m starting from creation of project.



In Spring Tool Suite

File -> New -> Maven Project

if u don't find maven in first list
then
file -> new -> other -> (search maven) maven project -> next





Select check box create simple project and then next(leave other option as it is).




Now we have to provide details of projects, e.g. name of project, package name etc.




then finish. It takes some time to create project. U can check progress in Progress tab.
In my IDE it creates Dynamic Web Module 2.5 version.
But I want to create 3.0 version.
To make our project Dynamic Web Module 3.0 version we have to do some extra work.

Steps to modify our project to 3.0
1) Right click on project and select properties





Then one dialog box will open



We have to search "project facet"



Then we change Dynamic web moduel to 3.0 and java 1.8






So we modify Dynamic web module to 3.0 and java 1.8 and selected my tomcat server and then apply and ok.
Even after this operation we realize that our deployment descriptor version haven't change.
To make change affect our project we have to first close project and then again open project.

Our pom.xml prompting one error that web.xml is missing.
Either u can create web.xml or you can follow this link, click here.
If link is not working then copy  paste url manually please.
https://stackoverflow.com/questions/31835033/web-xml-is-missing-and-failonmissingwebxml-is-set-to-true

Here I m avoiding to create web.xml.
Here my pom.xml code



pom.xml

<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.first</groupId>
  <artifactId>WebMVCSample</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>First Sample</name>
  <description>WEB MVC Project using maven n Spring tool suite.</description>

   <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jdk.version>1.8</jdk.version>
<spring.version>4.3.10.RELEASE</spring.version>
<maven.compiler.version>3.1</maven.compiler.version>
<maven.war.version>2.6</maven.war.version>
</properties>

   <!-- To avoid compiler and jre version -->
   <build>
    <plugins>
        <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven.compiler.version}</version>
        <configuration>
            <source>${jdk.version}</source>
            <target>${jdk.version}</target>
        </configuration>
    </plugin>

    <!-- To avoid web.xml error -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>${maven.war.version}</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </plugin>
    </plugins>
</build>



<dependencies>

<dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>${spring.version}</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

</dependencies>

</project>



I am using constants class to use some constants values.

Constants.java

package org.first.constant;

public class Constants {

public static final String WEB_PACKAGE_NAME   = "org.first.web";
public static final String VIEW_PREFIX_PATH = "/WEB-INF/views/";
public static final String VIEW_SUFFIX_PATH = ".jsp";
public static final String BASE_PACKAGE = "org.first";

}


This class is used for servlet mapping and resolved view mapping.

WebConfig.java

package org.first.config;
import org.first.constant.Constants;
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.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@EnableWebMvc
@ComponentScan(Constants.WEB_PACKAGE_NAME)
public class WebConfig extends WebMvcConfigurerAdapter{

@Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix(Constants.VIEW_PREFIX_PATH);
resolver.setSuffix(Constants.VIEW_SUFFIX_PATH);
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
configurer.enable();
}

}

We are just using this class for sake of requirements of coding so I m not discussing this class too much.

RootConfig.java

package org.first.config;
import org.first.constant.Constants;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@ComponentScan(basePackages={Constants.BASE_PACKAGE}, excludeFilters={@Filter(type=FilterType.ANNOTATION, value=EnableWebMvc.class)})
public class RootConfig {

}


Above two classes we are using in app initialize class.


SampleWebAppInitializer.java

package org.first.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class SampleWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{

@Override
protected String[] getServletMappings(){
return new String[]{"/"};
}
@Override
protected Class<?>[] getRootConfigClasses(){
return new Class<?>[] {RootConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses(){
return new Class<?>[] {WebConfig.class};
}
}

Finally our controller class

SampleController.java

package org.first.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class SampleController {

@RequestMapping(value="/", method=RequestMethod.GET)
public String home(){
return "test";
}
}

we have to create WEB-INF folder inside webapp folder.
path of webapp folder: src -> main -> webapp
and views folder inside WEB-INF folder.
My test.jsp file path:  /src/main/webapp/WEB-INF/views/test.jsp

content of test.jsp

test.jsp
<h1>Test jsp</h1>

After we complete our code then we have to maven update our project.
Not compulsory but some time requires.




Right click project then maven -> update project




select force update of snaphosts/releases then ok.
add in your server and then try to run.



This is my output.