Friday, 28 August 2020

Simple java http get example java net http get


Here I am calling simple java http get method and passing parameter with url 

url suppose : https://jsonmock.anywebsite.com/api/movies/search/?Title=spiderman

here Title is parameter that I will pass to with my url

anywebsite is replaced with the name of code testing web site, hence this url will not work

but if I hit correct url in chrome (as it is simple get request no need of postman or insomnia tool)

it would return below result

{"page":1,"per_page":10,"total":13,"total_pages":2,"data":[{"Title":"Italian Spiderman","Year":2007,"imdbID":"tt2705436"},{"Title":"Superman, Spiderman or Batman","Year":2011,"imdbID":"tt2084949"},{"Title":"Spiderman","Year":1990,"imdbID":"tt0100669"},{"Title":"Spiderman","Year":2010,"imdbID":"tt1785572"},{"Title":"Fighting, Flying and Driving: The Stunts of Spiderman 3","Year":2007,"imdbID":"tt1132238"},{"Title":"Spiderman and Grandma","Year":2009,"imdbID":"tt1433184"},{"Title":"The Amazing Spiderman T4 Premiere Special","Year":2012,"imdbID":"tt2233044"},{"Title":"Amazing Spiderman Syndrome","Year":2012,"imdbID":"tt2586634"},{"Title":"Hollywood's Master Storytellers: Spiderman Live","Year":2006,"imdbID":"tt2158533"},{"Title":"Spiderman 5","Year":2008,"imdbID":"tt3696826"}]}

Data and   OuterObj is the class according to this json data type.


I have maven java project 

this code would work with this dependency

Please add this dependency in your pom.xml


<dependency>

<groupId>com.google.code.gson</groupId>

<artifactId>gson</artifactId>

<version>2.8.5</version>

</dependency>


In this code I haven't did null checking, please do null checking


package org.hacker.rank.test;


import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.Reader;

import java.net.MalformedURLException;

import java.net.URL;

import java.util.List;


import com.google.gson.Gson;


public class HttpGet {


public static void main(String[] args) {

func("spiderman");

}


static void func(String substr) {

try {

//calling url and passing substr as parameter

URL url = new URL("https://jsonmock.hackerrank.com/api/movies/search/?Title="+substr);

//get inputstream

InputStream input = url.openStream();

//taking it into reader 

Reader reader = new InputStreamReader(input, "UTF-8");

//converting reader into our desire object

//after this object we can use it according to us

                OuterObj outerObj = new Gson().fromJson(reader, OuterObj.class);

List<Data> data = outerObj.getData();

System.out.println(outerObj);

catch (MalformedURLException e) {

e.printStackTrace();

catch (IOException e) {

e.printStackTrace();

}

return;

}


}




class Data{

private String Title;

private int Year;

private String imdbID;

public Data() {

//empty constructor

}

public String getTitle() {

return Title;

}

public void setTitle(String title) {

Title = title;

}

public int getYear() {

return Year;

}

public void setYear(int year) {

Year = year;

}

public String getImdbID() {

return imdbID;

}

public void setImdbID(String imdbID) {

this.imdbID = imdbID;

}

@Override

public String toString() {

return "Title: "+Title+"     Year: "+Year+"     imdbID: "+imdbID;

}

}


class OuterObj{

private int page;

private int per_page;

private int total;

private List<Data> data;

public OuterObj() {

//empty constructor

}


public int getPage() {

return page;

}

public void setPage(int page) {

this.page = page;

}

public int getPer_page() {

return per_page;

}

public void setPer_page(int per_page) {

this.per_page = per_page;

}

public int getTotal() {

return total;

}

public void setTotal(int total) {

this.total = total;

}

public List<Data> getData() {

return data;

}

public void setData(List<Data> data) {

this.data = data;

}

@Override

public String toString() {

return "page: "+page+"     per_page: "+per_page+"     total: "+total+"     data: "+data;

}

}


I was failed to complete this task in stipulated time, hope it would help me or others in future.

Thanks


Sunday, 28 April 2019

Shortest distinct characters sub string from original string

package org.liferayasif;

public class ShortestSubStringAllChars {

public static void main(String[] args) {

//By default original string is lower case alphabets
String originalString = "dfadsaaa";

//validation for string must not empty
if(originalString==null || originalString.length()==0) {
System.out.println("Please provide string of length > 0");
return ;
}

//get distinct string from original string
String distinctString = getDistinctString(originalString);
System.out.println("distinctString: "+distinctString);

//sorted distinct string in ascending order
String sortedDistinctString = sort(distinctString);
System.out.println("distinctString after sorting: "+sortedDistinctString);

int numOfDistinctChars = distinctString.length();

int subStringStartingIndex = 0;
int subStringEndingIndex = numOfDistinctChars;

boolean flag = false;

for(int j=0 ; j<originalString.length() ; j++) {

subStringStartingIndex = 0;

if(j!=0) {
subStringEndingIndex = numOfDistinctChars + j;
}

for(;;) {

/*getting substring from original string starting from 0 to distinct string length
* then shifting location of substring one by one
* e.g len of distinct string = 4 then will get substring from original string of size
* 4 and get all substring of size 4 till end of substring, if all distinct characters
* not found in this range then increasing substring size by one and again same operation
* shifting from left to right one by one
*/
String subString = originalString.substring(subStringStartingIndex, subStringEndingIndex);
System.out.println("subString: "+subString );

//get distinct characters substring from original substring
String distinctSubString = getDistinctString(subString);

//sort distinct sub string
String distinctSortedSubString = sort(distinctSubString);

/*compare sorted distinct string with sorted distinct sub string
* if match then this substring having all distinct characters
* which we requires
* once found we break infinite loop
* and set a flag to break outer loop
*/
if(distinctSortedSubString.equals(sortedDistinctString)) {
System.out.println("found: "+subString.length() + "   "+j+ "  "+subStringStartingIndex+" "+subString);
flag = true;
break;
}
/*to avoid index out of bound exception we have to check length of end substring index
* and if it reach to length of original string then finish the inner loop
*/
if(subStringEndingIndex==originalString.length()) {
break;
}
subStringEndingIndex +=1;
subStringStartingIndex++;
}
//to break outer loop if found solution
if(flag) {
break;
}
}
}

//Get distinct characters string from original string
private static String getDistinctString(String originalString) {

char[] ca = originalString.toCharArray();
String res = "";

res = res + ca[0];

for(int i=1 ; i<originalString.length() ; i++) {
if(!res.contains(ca[i]+"")) {
res = res + ca[i];
}
}
return res;
}

//Sort string in ascending order
private static String sort(String originalString) {

char[] ca = originalString.toCharArray();

for(int i=0 ; i<originalString.length() ; i++) {

for(int j=i+1 ; j<originalString.length() ; j++) {
if(ca[i]-ca[j]>=0) {
char t = ca[i];
ca[i] = ca[j];
ca[j] = t;
}
}
}
return new String(ca);
}

}

Tuesday, 8 May 2018

request.getContextPath() Liferay 7, display image liferay

In this post I just want to mention the value of 'request.getContextPath()' in liferay 7.
Before 7 'request.getContextPath()' return the name of custom portlet project.
Now this time it is returning

/o/base package name

Here '/o' appended with our base package name.

Suppose I gave "org.liferayasif.restautrant" package name at the time of creation of 
liferay module project then 

'request.getContextPath()' will return : '/o/org.liferayasif.restautrant'

if we want to display our module project name instead of package name we have to add one line in 'bnd.bnd' file and the code is

Web-ContextPath: /custom-module-project name

Web-ContextPath: /RestaurantProject (RestaurantProject is my module project name)

now the value return by 
'request.getContextPath()' will be '/o/RestaurantProject'

RestaurantProject is my module project name.

'request.getContextPath()' having lots of use but I am using it to display my custom image that I stored inside module portlet.

I created one folder namely 'images' and the path is
'/META-INF/resources/images'

inside this images folder I stored my images and displaying in jsp pages.
Code to display images in my jsp page is

<img src="<%= request.getContextPath() %>/images/menu_list4.jpg">

if you don't want to use request.getContextPath() then you can directly write your porlet name with prefix '/o'.

Like this

<img src="/o/custom-module-porltet-name/images/menu_list.jpg" alt="problem">

<img src="/o/RestaurantProject/images/menu_list.jpg" alt="problem">

RestaurantProject: is my custom module portlet name.

Where 'menu_list.jpg' is my pic name.

Spring 4 Security MVC Form Login Example - Spring MVC Tutorial for Beginners Example










This spring mvc project is purely based on annotation.
No xml files used here.
Configuration with simple jdbc.
No hibernate.

I implemented this code by using this video

https://www.youtube.com/watch?v=sHETKJUBTyk


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

(Select project that we just created)




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.liferayasif.login.example</groupId>
  <artifactId>FirstSecurity</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  
    <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <jdk.version>1.8</jdk.version> 
  <springframework.version>4.3.0.RELEASE</springframework.version>
  <springframework.security.version>4.0.4.RELEASE</springframework.security.version>
  <hibernate.version>4.3.6.Final</hibernate.version>
  <maven.compiler.version>3.1</maven.compiler.version>
  <maven.war.version>2.6</maven.war.version>
  <mysql.connector.version>5.1.31</mysql.connector.version>
  <testng.version>6.9.4</testng.version>
      <mockito.version>1.10.19</mockito.version>
      <h2.version>1.4.187</h2.version>
      <dbunit.version>2.2</dbunit.version>
      <joda-time.version>2.3</joda-time.version>
      <dozer.version>5.4.0</dozer.version>
      <jackson.version>2.2.3</jackson.version>
  </properties>
  
  
  <dependencies>
 
  <!-- Spring Core -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${springframework.version}</version>
</dependency>

<!-- Spring Webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>

<!-- Spring Security -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>${springframework.security.version}</version>
</dependency>
 
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>${springframework.security.version}</version>
    </dependency>

  <!-- Spring JDBC -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${springframework.version}</version>
</dependency>

  <!-- Servlet -->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    </dependency>
    
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>2.3.1</version>
    </dependency>
    
    <!-- JSTL -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency> 

<!-- MySQL -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql.connector.version}</version>
    </dependency>
  </dependencies>
  
  <!-- 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>
              <warSourceDirectory>src/main/webapp</warSourceDirectory>
              <warName>SpringMVCLoginExample</warName>
                <failOnMissingWebXml>false</failOnMissingWebXml>
             </configuration>
         </plugin>
     </plugins>
</build>  

</project>


MySql query to create database and tables that I m using here

create database springmvclogin;

use springmvclogin;

create table users(
id int not null auto_increment,
    username varchar(60),
    password varchar(60),
    primary key(id)
);


create table user_roles(
role_id int not null auto_increment,
    username varchar(60),
    user_role varchar(60),
    primary key(role_id)
);


Data inside my tables are 

For users table:





For user_roles table:


Java Class file hierarchy





Now my classes are

1. UserInfo.java

package org.liferayasif.login.example.model;

public class UserInfo {

private String username;
private String password;

public UserInfo(){}

public UserInfo(String username, String password) {

super();
this.username = username;
this.password = password;
}

public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}



2. LoginDao.java (interface)

package org.liferayasif.login.example.dao;

import java.util.List;

import org.liferayasif.login.example.model.UserInfo;

public interface LoginDao {

public UserInfo findUserInfoByUserName(String userName);
public List<String> getUserRolesByUserName(String userName);
}


3. LoginDaoImpl.java

package org.liferayasif.login.example.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;


import org.liferayasif.login.example.model.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;

@Repository
public class LoginDaoImpl implements LoginDao{

NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@Autowired
public void setNamedParameterJdbcTemplate(NamedParameterJdbcTemplate namedParameterJdbcTemplate) throws DataAccessException{
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
}
@Override
public UserInfo findUserInfoByUserName(String username) {
String query = "select * from users where username=:username";
try{
UserInfo userInfo = namedParameterJdbcTemplate.queryForObject(query, getSqlParameterByModel(username, ""), new UserInfoMapper());
return userInfo;
}
catch(EmptyResultDataAccessException e){
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}

private SqlParameterSource getSqlParameterByModel(String userName, String password){
MapSqlParameterSource paramSource = new MapSqlParameterSource();
paramSource.addValue("username", userName);
paramSource.addValue("password", password);
return paramSource;
}
private static final class UserInfoMapper implements RowMapper<UserInfo>{
public UserInfo mapRow(ResultSet rs, int rowNum) throws SQLException{
String userName = rs.getString("username");
String password = rs.getString("password");
return new UserInfo(userName, password);
}
}
@Override
public List<String> getUserRolesByUserName(String username) {
String query = "select user_role from user_roles WHERE username=:username";
List<String> roles = namedParameterJdbcTemplate.queryForList(query, getSqlParameterByModel(username, ""), String.class);
return roles;
}
}


4. LoginService.java

package org.liferayasif.login.example.service;

import java.util.ArrayList;
import java.util.List;

import org.liferayasif.login.example.dao.LoginDao;
import org.liferayasif.login.example.model.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class LoginService implements UserDetailsService{

@Autowired
LoginDao loginDao;
public void setLoginDao(LoginDao loginDao) {
this.loginDao = loginDao;
}


@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
UserInfo userInfo = loginDao.findUserInfoByUserName(userName);
if(userInfo==null){
throw new UsernameNotFoundException("user name not found");
}
List<String> roles = loginDao.getUserRolesByUserName(userName);
List<GrantedAuthority> grantedAuthorityList = new ArrayList<GrantedAuthority>(); 
if(roles!=null){
for(String role : roles){
GrantedAuthority authority = new SimpleGrantedAuthority(role);
grantedAuthorityList.add(authority);
}
}
UserDetails userDetails = new User(userInfo.getUsername(), userInfo.getPassword(), grantedAuthorityList);
return userDetails;
}

}


5. SecurityConfig.java

package org.liferayasif.login.example.config;

import org.liferayasif.login.example.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
LoginService loginServiceImpl;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(loginServiceImpl);
auth.authenticationProvider(authenticationProvider());
}
@Bean
public DaoAuthenticationProvider authenticationProvider(){
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(loginServiceImpl);
return authenticationProvider;
}
@Override
protected void configure(HttpSecurity http) throws Exception{
http.csrf().disable();
http.authorizeRequests().antMatchers("/login").permitAll();
http.authorizeRequests().antMatchers("/", "/home").access( "hasRole('ROLE_ADMIN')" );
http.authorizeRequests().and().formLogin()
.loginProcessingUrl("/j_spring_security_check")
.loginPage("/login")
.defaultSuccessUrl("/home")
.failureUrl("/login?error=true")
.usernameParameter("username")
.passwordParameter("password")
.and().logout().logoutUrl("/j_spring_security_logout").logoutSuccessUrl("/login");
}
}



6. WebConfig.java

package org.liferayasif.login.example.config;

import javax.naming.NamingException;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@EnableWebMvc
@Configuration
@ComponentScan({"org.liferayasif.login.example"})
@Import({SecurityConfig.class})
public class WebConfig extends WebMvcConfigurerAdapter{

@Autowired
DataSource dataSource;
@Bean
public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate(){
return new NamedParameterJdbcTemplate(dataSource);
}
@Bean
public DataSource getDataSource() throws NamingException{
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/springmvclogin");
dataSource.setPassword("root");
dataSource.setUsername("root");
return dataSource;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/resources/**").addResourceLocations("/resources");
}
@Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
internalResourceViewResolver.setViewClass(JstlView.class);
internalResourceViewResolver.setPrefix("/WEB-INF/jsp/");
internalResourceViewResolver.setSuffix(".jsp");
return internalResourceViewResolver;
}
}


7. SecurityInitializer.java

package org.liferayasif.login.example.config;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer{

}


8. WebInit.java

package org.liferayasif.login.example.config;

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

public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer{

@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{WebConfig.class};
}

@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}

@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}

}


9. LoginController.java

package org.liferayasif.login.example.controller;

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

@Controller
public class LoginController {

@RequestMapping(value="/login", method = RequestMethod.GET)
public ModelAndView login(@RequestParam(value="error", required = false) String error){
ModelAndView mav = new ModelAndView();
if(error!=null)
mav.addObject("error", "username or password is incorrect");
mav.setViewName("login/login");
return mav;
}
@RequestMapping(value={"/", "/home"}, method = RequestMethod.GET)
public ModelAndView home(){
ModelAndView mav = new ModelAndView();
mav.setViewName("home/home");
return mav;
}
}


my jsp folder hierarchy




Add your tomcat server and run.

url: http://localhost:8080/SpringMVCLoginExample/login

credentials: 

User Name: admin
Password: 1234

Please give me your feedback.







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.

Monday, 4 December 2017

Tile Integration with Spring


Tile integration with Spring.



My System configuration:

Windows 10
Spring Tool Suite
Platform: Eclipse Neon.1 (4.6.1)
java version "1.8.0_131"




To create Tile Integration with Spring we have to follow these steps:




1)Create a maven project




2)Select Maven project





3) Select option create a simple project(skip archetype selection)







4) Give group id and artifact id and some extra details and then finish.








After this step our maven project will be created but showing some error.
One error is inside pom.xml





*Note: This image is for explanation purpose only, value of tag may be different from current project.
           Please follow only error part and how to remove.



If u hold your mouse on cross sign/error place then u can see this





and the message is:
                             web.xml is missing and <failOnMissingWebXml> is set to true

To avoid this problem we have to add some code in pom.xml (I will show u shortly).

Second thing is not an error but it is showing older version of Deployment Descriptor. We have to change this too.



Now my 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.asif.tile</groupId>
  <artifactId>TileSpringIntegration</artifactId>
  <version>0.1</version>
  <packaging>war</packaging>
  <name>Tile Integration with Spring</name>
  <description>In this project I am integrating tile with spring4</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>
  <javax.validation.constraint.version>2.0.0.Final</javax.validation.constraint.version>
  </properties>
  
  <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>javax.servlet</groupId>
   <artifactId>jstl</artifactId>
   <version>1.2</version>
</dependency>

<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.1</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.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>

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.6</version>
</dependency>
 
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.3.10.RELEASE</version>
    <scope>test</scope>
</dependency>
 
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-all</artifactId>
    <version>1.10.19</version>
    <scope>test</scope>
</dependency>
 
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>${javax.validation.constraint.version}</version>
</dependency>

<dependency>
    <groupId>org.apache.tiles</groupId>
    <artifactId>tiles-jsp</artifactId>
    <version>3.0.7</version>
</dependency>
 
</dependencies>

</project>



After saving pom.xml you have to upate maven project.
Even after this if you observe deployment descriptor still it is showing old version like this


*Note: This image is for explanation purpose only, value of tag may be different from current project.

           Please follow only error part and how to remove.




To change it to latest version we have to close project and then open again.

Now once I closed project and open again then you can see change






*Note: This image is for explanation purpose only, value of tag may be different from current project.
           Please follow only error part and how to remove.


You can check that now Deployment descriptor becomes 3.1 previously it was 2.5.


Simply maven update your project.
Now our project is created and having no error.


We will see our coding part now.
In this project for all configurations we are using Java class only, no xml file.


First we will create TileWebConfig class in which we will do configuration of our tile.
Here is our class


package org.asif.tile.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.springframework.web.servlet.view.tiles3.TilesConfigurer;
import org.springframework.web.servlet.view.tiles3.TilesViewResolver;

@Configuration
@EnableWebMvc //Enable Spring MVC
@ComponentScan("org.asif.tile.web") //Enable component-scanning
public class TileWebConfig extends WebMvcConfigurerAdapter{

@Bean
public TilesConfigurer tilesConfigurer(){
TilesConfigurer tilesConfigurer = new TilesConfigurer();
tilesConfigurer.setDefinitions(new String[]{"/WEB-INF/layout/tiles.xml"});
tilesConfigurer.setCheckRefresh(true);
return tilesConfigurer;
}


@Bean
public ViewResolver viewResolver() {
return new TilesViewResolver();
}

//configure static content handling
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
configurer.enable();
}

}


*NOTE: If you change your package name then please don't forget to change 
@ComponentScan("Here please give your package name")

If you forgot to change package name or any miss match to provide proper package then may be project deploy and you can see your project in tomcat manager but if you try to access your project it gives you error that path not found.
Please take care of this.

tilesConfigurer.setDefinitions(new String[]{"/WEB-INF/layout/tiles.xml"});
This is the place where I have to keep my tiles.xml file.



Spring web Initialize class 

package org.asif.tile.config;

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

public class TileSpringIntegrationWebAppInitializer  extends AbstractAnnotationConfigDispatcherServletInitializer{

@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{RootConfig.class};
}

//Specify configuration class
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{TileWebConfig.class};
}

//Map DispatcherServlet to /
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}

}




RootConfig class

package org.asif.tile.config;

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={"org.asif.tile"}, excludeFilters={@Filter(type=FilterType.ANNOTATION, value=EnableWebMvc.class)})
public class RootConfig {

}



tilesConfigurer.setDefinitions(new String[]{"/WEB-INF/layout/tiles.xml"});
This is the place where I have to keep my tiles.xml file.

First we have to create folder "WEB-INF" inside webapp folder and then "layout" folder.


tiles.xml

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
<definition name="base" template="/WEB-INF/layout/page.jsp">
<put-attribute name="header" value="/WEB-INF/layout/header.jsp" />
<put-attribute name="footer" value="/WEB-INF/layout/footer.jsp" />
</definition>
<definition name="home" extends="base">
<put-attribute name="body" value="/WEB-INF/views/home.jsp" />
</definition>
<definition name="registerForm" extends="base">
<put-attribute name="body" value="/WEB-INF/views/register-form.jsp" />
</definition>
</tiles-definitions> 


Explanation:
Here we are adding one header and one footer page inside "page.jsp" and passing our required jsp page as body.

<definition name="base" template="/WEB-INF/layout/page.jsp">
<put-attribute name="header" value="/WEB-INF/layout/header.jsp" />
<put-attribute name="footer" value="/WEB-INF/layout/footer.jsp" />
</definition>

Above page.jsp page behave as base page for all where we included header and footer.jsp.

<definition name="home" extends="base">
<put-attribute name="body" value="/WEB-INF/views/home.jsp" />
</definition>

In this tag we extends our base page where we already included header and footer.jsp and then redirect to our required jsp page.
here we are redirecting to home.jsp.

Now we will discuss our page.jsp

<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="t" %>
<%@ page session="false" %>

<html>
<head>
<title>Spittr</title>
<link rel="stylesheet" type="text/css" href="<s:url value="/resources/style.css" />" >
</head>
<body>
<div id="header">
<t:insertAttribute name="header" />
</div>
<div id="content">
<t:insertAttribute name="body" />
</div>
<div id="footer">
<t:insertAttribute name="footer" />
</div>
</body>
</html>


Explanation

<div id="header">
<t:insertAttribute name="header" />
</div>

Including header part
header attribute coming from tiles.xml file

<put-attribute name="header" value="/WEB-INF/layout/header.jsp" />



<div id="footer">
<t:insertAttribute name="footer" />
</div>

including footer part:
this is attribute name="footer" from tiles.xml file
<put-attribute name="footer" value="/WEB-INF/layout/footer.jsp" />

for body 

<div id="content">
<t:insertAttribute name="body" />
</div>

attribute from tiles.xml
<put-attribute name="body" value="/WEB-INF/views/home.jsp" />


header.jsp
<h2>Header.jsp</h2>

footer.jsp
<h2>Footer.jsp</h2>


path of footer.jsp, header.jsp, page.jsp and tiles.xml is

/webapp/WEB-INF/layout/



Now we will create our controller class


package org.asif.tile.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HomeController {

@RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView myModelMethod(Model model){
    ModelAndView mav = new ModelAndView("home");
    return mav;
    }
@RequestMapping(value="/registerform", method=RequestMethod.GET)
public ModelAndView registerForm(){
ModelAndView mav = new ModelAndView("registerForm");
    return mav;
}
}

ModelAndView mav = new ModelAndView("home");

here "home" must match with tiles.xml file name="home" tag.


<definition name="home" extends="base">
<put-attribute name="body" value="/WEB-INF/views/home.jsp" />
</definition>

here "home" view set in ModelAndView class view name will match with tiles.xml <definition name="home"
and our view will be <put-attribute name="body" value="/WEB-INF/views/home.jsp" />, home.jsp.

Here header and footer already added in page.jsp and that jsp we are using as base in tiles. 
So whenever we return a view from our controller will be added by header and footer jsp page.



home.jsp


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<h1>Welcome Tile Integration</h1>

<a href="<c:url value="/registerform" />">Register</a>

its simple jsp where I am redirecting to other page, this first hit our controller and from controller we are going to decide which has to choose.


package org.asif.tile.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HomeController {

@RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView myModelMethod(Model model){
    ModelAndView mav = new ModelAndView("home");
    return mav;
    }
@RequestMapping(value="/registerform", method=RequestMethod.GET)
public ModelAndView registerForm(){
ModelAndView mav = new ModelAndView("registerForm");
    return mav;
}
}


url : http://localhost:8080/TileSpringIntegration/

where 8080 depends on your tomcat port

myModelMethod() -> this method will hit on this url:  http://localhost:8080/TileSpringIntegration/

my home jsp page in browser



Where Header.jsp and Footer.jsp are added automatically.

path of home and register-form.jsp :   /webapp/WEB-INF/views

content of home.jsp

Welcome Tile Integration

Register


this home.jsp as return from controller as view and added as a body in the page using tile.

When we click Register link in home page then we will hit 

@RequestMapping(value="/registerform", method=RequestMethod.GET)
public ModelAndView registerForm(){
ModelAndView mav = new ModelAndView("registerForm");
     return mav;
}

and will hit tiles.xml file


<definition name="registerForm" extends="base">
<put-attribute name="body" value="/WEB-INF/views/register-form.jsp" />
</definition>

now it would redirect to register-form.jsp 

register-form.jsp content.

<h1>Register Form jsp</h1>