4

JDK Java path

Set Java path permanently

				
					vim /etc/profile

# add 
export JAVA_HOME=/usr/lib/jvm/jdk-11
export PATH=$PATH:$JAVA_HOME/bin
				
			

List available jdk installed and change as required

				
					archlinux-java status

# Available Java environments:
  # java-17-openjdk
  # java-21-jdk
  # jdk-11 (default)

				
			

JSP + Servlet + OAuth + Maven + MySQL

JSP application which does the authentication using the Google OAuth. Once logged in, it will get the details from the MySQL database.

 

				
					<!-- 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.brains</groupId>
	<artifactId>oauth</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>oauth Maven Webapp</name>
	<!-- FIXME change it to the project's website -->
	<url>http://www.example.com</url>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>1.7</maven.compiler.source>
		<maven.compiler.target>1.7</maven.compiler.target>
	</properties>
	<dependencies>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
		</dependency>
		<dependency>
			<groupId>com.google.api-client</groupId>
			<artifactId>google-api-client</artifactId>
			<version>1.22.0</version>
		</dependency>
		<dependency>
			<groupId>com.google.http-client</groupId>
			<artifactId>google-http-client</artifactId>
			<version>1.22.0</version>
		</dependency>
		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
			<version>2.7</version>
		</dependency>
		<dependency>
			<groupId>com.google.http-client</groupId>
			<artifactId>google-http-client-jackson</artifactId>
			<version>1.22.0</version>
		</dependency>
		<dependency>
			<groupId>com.google.apis</groupId>
			<artifactId>google-api-services-oauth2</artifactId>
			<version>v2-rev120-1.22.0</version>
		</dependency>
		<dependency>
			<groupId>com.google.api-client</groupId>
			<artifactId>google-api-client</artifactId>
			<version>1.22.0</version>
		</dependency>
		<dependency>
			<groupId>com.google.apis</groupId>
			<artifactId>google-api-services-plus</artifactId>
			<version>v1-rev453-1.22.0</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.33</version>
		</dependency>
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-api</artifactId>
			<version>2.20.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-core</artifactId>
			<version>2.20.0</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>oauth</finalName>
		<pluginManagement>
			<!-- lock down plugins versions to avoid using Maven 
				defaults (may be moved to parent pom) -->
			<plugins>
				<plugin>
					<artifactId>maven-clean-plugin</artifactId>
					<version>3.1.0</version>
				</plugin>
				<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
				<plugin>
					<artifactId>maven-resources-plugin</artifactId>
					<version>3.0.2</version>
				</plugin>
				<plugin>
					<artifactId>maven-compiler-plugin</artifactId>
					<version>3.8.0</version>
				</plugin>
				<plugin>
					<artifactId>maven-surefire-plugin</artifactId>
					<version>2.22.1</version>
				</plugin>
				<plugin>
					<artifactId>maven-war-plugin</artifactId>
					<version>3.2.2</version>
				</plugin>
				<plugin>
					<artifactId>maven-install-plugin</artifactId>
					<version>2.5.2</version>
				</plugin>
				<plugin>
					<artifactId>maven-deploy-plugin</artifactId>
					<version>2.8.2</version>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>
</project>

				
			
				
					<!-- web.xml -->
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
 
  <context-param>
  	<param-name>database</param-name>
  	<param-value>oauth</param-value>
  </context-param>
  <context-param>
  	<param-name>user</param-name>
  	<param-value>root</param-value>
  </context-param>
  <context-param>
  	<param-name>password</param-name>
  	<param-value>root</param-value>
  </context-param>
  
  <listener>
  	<listener-class>com.brains.listeners.DatabaseContextListener</listener-class>
  </listener>
  
  <servlet>
  	<servlet-name>LoginServlet</servlet-name>
  	<display-name>LoginServlet</display-name>
  	<description></description>
  	<servlet-class>com.brains.LoginServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>LoginServlet</servlet-name>
  	<url-pattern>/login</url-pattern>
  </servlet-mapping>
</web-app>

				
			
				
					<!-- index.jsp -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://apis.google.com/js/platform.js" async defer></script>
<meta name="google-signin-scope" content="profile email">
<meta name="google-signin-client_id"
     content="434006981147-vcaa735q92hmajglm2m7vbeb981p5h6t.apps.googleusercontent.com">

<title>Servlet OAuth example</title>
</head>
<body>
	<h2>Servlet OAuth example</h2>
	<br>
	<div class="g-signin2" data-onsuccess="onSignIn"></div>
	
	<script>
	function onSignIn(googleUser) {
      var profile = googleUser.getBasicProfile();
      console.log('ID: ' + profile.getId());
      console.log('Name: ' + profile.getName());
      console.log('Image URL: ' + profile.getImageUrl());
      console.log('Email: ' + profile.getEmail());
      console.log('id_token: ' + googleUser.getAuthResponse().id_token);

     //do not post above info to the server because that is not safe.
     //just send the id_token

      var redirectUrl = 'login';
      //using jquery to post data dynamically
      var form = $('<form action="' + redirectUrl + '" method="post">' +
                          '<input type="text" name="id_token" value="' +
                           googleUser.getAuthResponse().id_token + '" />' +
                                                                '</form>');
    $('body').append(form);
    form.submit();
    }

	</script>
</body>
</html>
				
			
				
					<!-- welcome-page.jsp -->
<%@ page isELIgnored="false" %>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link rel="stylesheet" href="resources/css/style.css" />

<title>Welcome</title>
</head>
<body>


<!--  forward to index page for login if user info is not in session  -->
<% if (session.getAttribute("ubName") == null) {%>
<jsp:forward page="/index.jsp"/>
<% } %>
<h3>Welcome  ${ubName}</h3>
<img alt="" src=${picture}  referrerpolicy="no-referrer">

<h4>Data from DB</h4>
<div class="m1">
	<div class="mytd">
		<div class="label">Name</div><div>${emp.name}</div>
	</div>
	<div class="mytd">
		<div class="label">Mobile</div><div>${emp.mobile}</div>
	</div>
	<div class="mytd">
		<div class="label">Email</div><div>${emp.email}</div>
	</div>
</div>




</body>
</html>
				
			
				
					/* style.css */

@charset "UTF-8";

body {
  font-family: Arial, Helvetica, sans-serif;
}

* {
  box-sizing: border-box;
}

/* style the container */
.container {
  position: relative;
  border-radius: 5px;
  background-color: #f2f2f2;
  padding: 20px 0 30px 0;
} 

/* style inputs and link buttons */
input,
.btn {
  width: 100%;
  padding: 12px;
  border: none;
  border-radius: 4px;
  margin: 5px 0;
  opacity: 0.85;
  display: inline-block;
  font-size: 17px;
  line-height: 20px;
  text-decoration: none; /* remove underline from anchors */
}

input:hover,
.btn:hover {
  opacity: 1;
}

/* add appropriate colors to fb, twitter and google buttons */
.fb {
  background-color: #3B5998;
  color: white;
}

.twitter {
  background-color: #55ACEE;
  color: white;
}

.google {
  background-color: #dd4b39;
  color: white;
}

/* style the submit button */
input[type=submit] {
  background-color: #04AA6D;
  color: white;
  cursor: pointer;
}

input[type=submit]:hover {
  background-color: #45a049;
}

/* Two-column layout */
.col {
  float: left;
  width: 50%;
  margin: auto;
  padding: 0 50px;
  margin-top: 6px;
}

/* Clear floats after the columns */
.row:after {
  content: "";
  display: table;
  clear: both;
}

/* vertical line */
.vl {
  position: absolute;
  left: 50%;
  transform: translate(-50%);
  border: 2px solid #ddd;
  height: 175px;
}

/* text inside the vertical line */
.vl-innertext {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  background-color: #f1f1f1;
  border: 1px solid #ccc;
  border-radius: 50%;
  padding: 8px 10px;
}

/* hide some text on medium and large screens */
.hide-md-lg {
  display: none;
}

/* bottom container */
.bottom-container {
  text-align: center;
  background-color: #666;
  border-radius: 0px 0px 4px 4px;
}

/* Responsive layout - when the screen is less than 650px wide, make the two columns stack on top of each other instead of next to each other */
@media screen and (max-width: 650px) {
  .col {
    width: 100%;
    margin-top: 0;
  }
  /* hide the vertical line */
  .vl {
    display: none;
  }
  /* show the hidden text on small screens */
  .hide-md-lg {
    display: block;
    text-align: center;
  }
}


.m1{
	width:300px;
}
.mytd{
	border:1px solid black;
	clear: both;
	padding: 10px;
	height: 30px;
}
.mytd>div{
	float: left;	
}
.label{
	font-weight: 900;
	padding-right:10px;
}
img{
	width:100px;
	height:100px;
}
				
			
				
					<!-- log4j2.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
    <Properties>
        <Property name="LOG_PATTERN">%d{yyyy-MM-dd'T'HH:mm:ss.SSSZ} %p %m%n</Property>
    </Properties>
 
    <Appenders>
        <Console name="console" target="SYSTEM_OUT" follow="true">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </Console>
    </Appenders>
 
    <Loggers>
        <Root level="info">
            <AppenderRef ref="console"/>
        </Root>
    </Loggers>
</Configuration>
				
			
				
					package com.brains;

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.brains.models.Employee;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;

/**
 * Servlet implementation class LoginServlet
 */
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private Connection conn;

	private static final Logger LOGGER = LogManager.getLogger(LoginServlet.class);
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		
		checkActiveSession(req, resp);
		
		resp.setContentType("text/html");
		try {
            String idToken = req.getParameter("id_token");
            GoogleIdToken.Payload payLoad = IdTokenVerifierAndParser.getPayload(idToken);
            String name = (String) payLoad.get("name");
            String email = payLoad.getEmail();

            HttpSession session = req.getSession(true);
            session.setAttribute("ubName", name);
            req.setAttribute("email", email);
            session.setAttribute("picture", payLoad.get("picture"));
            
            getUserDetailsFromDB(req);
            
            req.getServletContext()
               .getRequestDispatcher("/welcome-page.jsp").forward(req, resp);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
	}

	private void getUserDetailsFromDB(ServletRequest req) {
		if(conn == null) {
			conn = (Connection) this.getServletContext().getAttribute("con");			
		}
		String loginEmail = (String) req.getAttribute("email");
		
		HttpSession session = ((HttpServletRequest) req).getSession(true);
		String str = "SELECT * FROM employee where email = '"+loginEmail+"'";

		try (
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(str)) {
            // Extract data from result set
            while (rs.next()) {
                //Retrieve by column name
                String name = rs.getString("name");
                String email = rs.getString("email");
                String mobile = rs.getString("mobile");
                // Add item
                Employee emp = new Employee(name, email, mobile);
                session.setAttribute("emp", emp);
            }

            session.setAttribute("title", "Top 5 fruits");
//            req.getRequestDispatcher("/WEB-INF/views/index.jsp").forward(req, resp);
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
	}
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		checkActiveSession(req, resp);
		req.getServletContext()
        .getRequestDispatcher("/welcome-page.jsp").forward(req, resp);
	}
	
	private void checkActiveSession(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
		HttpSession session = req.getSession();
        String userName = (String) session.getAttribute("ubName");
        LOGGER.warn("checkActiveSession: "+ userName);
        if(userName == null) {
        	req.getRequestDispatcher("index.jsp").include(req, resp);
        }
	}
}

				
			
				
					package com.brains;

import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;

public class IdTokenVerifierAndParser {
	private static final String GOOGLE_CLIENT_ID = "434006981147-vcaa735q92hmajglm2m7vbeb981p5h6t.apps.googleusercontent.com";

    public static GoogleIdToken.Payload getPayload (String tokenString) throws Exception {

        JacksonFactory jacksonFactory = new JacksonFactory();
        GoogleIdTokenVerifier googleIdTokenVerifier =
                            new GoogleIdTokenVerifier(new NetHttpTransport(), jacksonFactory);

        GoogleIdToken token = GoogleIdToken.parse(jacksonFactory, tokenString);

        if (googleIdTokenVerifier.verify(token)) {
            GoogleIdToken.Payload payload = token.getPayload();
            if (!GOOGLE_CLIENT_ID.equals(payload.getAudience())) {
                throw new IllegalArgumentException("Audience mismatch");
            } else if (!GOOGLE_CLIENT_ID.equals(payload.getAuthorizedParty())) {
                throw new IllegalArgumentException("Client ID mismatch");
            }
            return payload;
        } else {
            throw new IllegalArgumentException("id token cannot be verified");
        }
    }
}

				
			
				
					package com.brains.models;

public class Employee {

	private String name;
	private String email;
	private String mobile;
	
	public Employee() {}
	public Employee(String name, String email, String mobile) {
		this.name = name;
		this.email = email;
		this.mobile = mobile;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getMobile() {
		return mobile;
	}
	public void setMobile(String mobile) {
		this.mobile = mobile;
	}
}

				
			
				
					package com.brains.listeners;

import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread;

public class DatabaseContextListener implements ServletContextListener {

	private static final Logger LOGGER = LogManager.getLogger(DatabaseContextListener.class);
	@Override
	public void contextInitialized(ServletContextEvent sce) {
		ServletContext context = sce.getServletContext();
		
		String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
		String DB_URL="jdbc:mysql://localhost:3307";
		String database = context.getInitParameter("database");
		String user = context.getInitParameter("user");
		String password = context.getInitParameter("password");
		
		try {
			Class.forName(JDBC_DRIVER);
			Connection con = DriverManager.getConnection(DB_URL+"/"+database+"?useSSL=false&allowPublicKeyRetrieval=true", user, password);
			context.setAttribute("con", con);
		} catch (SQLException | ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		
		Enumeration<Driver> drivers = DriverManager.getDrivers();
	    Driver d = null;
	    while (drivers.hasMoreElements()) {
	        try {
	            d = drivers.nextElement();
	            DriverManager.deregisterDriver(d);
	            LOGGER.warn(String.format("Driver %s deregistered", d));
	        }
	        catch (SQLException ex) {
	            LOGGER.warn(String.format("Error deregistering driver %s", d), ex);
	        }
	    }
	    try {
	        AbandonedConnectionCleanupThread.checkedShutdown();
	    }
	    catch (Exception e) {
	    	LOGGER.warn("SEVERE problem cleaning up: " + e.getMessage());
	        e.printStackTrace();
	    }
	  }
}

				
			

Related Tutorials

				
					<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.0.2</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.brains.jpa.hibernate</groupId>
	<artifactId>jpa-hibernate-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>jpa-hibernate-demo</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

				
			
				
					spring.datasource.url=jdbc:h2:mem:testdb;NON_KEYWORDS=USER;DB_CLOSE_ON_EXIT=FALSE
spring.h2.console.enabled=true
spring.jpa.defer-datasource-initialization=true

# Turn Statistics ON
#spring.jpa.properties.hibernate.generate_statistics=true
logging.level.org.hibernate.stat=debug
#logging.level.root=trace
# Show all queries
spring.jpa.show-sql=true

# Format the queries
spring.jpa.properties.hibernate.format_sql=true
				
			
				
					package com.brains.jpa.hibernate.jpahibernatedemo.entity;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.OneToMany;
import lombok.AccessLevel;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.Setter;

@Entity
@Data
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Course {
	
	@Id
	@GeneratedValue
	private Long id;
	
	@NonNull
	private String name;
	
	@Setter(AccessLevel.NONE)
	@OneToMany(mappedBy = "course", fetch = FetchType.LAZY)
	private List<Review> reviews = new ArrayList<>();
	
	@ManyToMany(mappedBy = "courses")
	@Setter(value = AccessLevel.NONE)
	private List<Student> students = new ArrayList<>();
	
	public void addStudent(Student student) {
		this.students.add(student);
	}
	
	public void addReview(Review review) {
		this.reviews.add(review);
	}
	
	public void removeReview(Review review) {
		this.reviews.remove(review);
	}
	
	@UpdateTimestamp
	private LocalDateTime lastUpdatedDate;

	@CreationTimestamp
	private LocalDateTime createdDate;
	
	public Course(String name) {
		this.name = name;
	}
}

				
			
				
					package com.brains.jpa.hibernate.jpahibernatedemo.entity;

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

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.OneToOne;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Entity
@Data @NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@RequiredArgsConstructor
public class Student {

	@Id
	@GeneratedValue
	private Long id;
	
	@NonNull
	@Column(nullable = false)
	private String name;
	
	@OneToOne(fetch = FetchType.LAZY)
	private Passport passport;
	
	@ToString.Exclude
	@ManyToMany
	@Setter(value = AccessLevel.NONE)
	@JoinTable(name = "STUDENT_COURSE", 
			joinColumns = @JoinColumn(name = "STUDENT_ID"),
			inverseJoinColumns = @JoinColumn(name = "COURSE_ID")
			)
	private List<Course> courses = new ArrayList<>();
	
	public void addCourse(Course course) {
		this.courses.add(course);
	}
}
				
			
				
					package com.brains.jpa.hibernate.jpahibernatedemo.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.OneToOne;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.ToString;

@Entity
@Data @NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@RequiredArgsConstructor
public class Passport {

	@Id
	@GeneratedValue
	private Long id;
	
	@NonNull
	@Column(nullable = false)
	private String number;
	
	@ToString.Exclude
	@OneToOne(fetch = FetchType.LAZY, mappedBy = "passport")
	private Student student;
}
				
			
				
					package com.brains.jpa.hibernate.jpahibernatedemo.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.ToString;

@Entity
@Data @NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@RequiredArgsConstructor
public class Review {

	@Id
	@GeneratedValue
	private Long id;
	
	@NonNull
	private String rating;
	
	@NonNull
	private String description;
	
	@ToString.Exclude
	@ManyToOne
	private Course course;
}

				
			
				
					insert into course(id, name, created_date, last_updated_date) 
values(10001, 'JPA in 5 steps', LOCALTIMESTAMP, LOCALTIMESTAMP);
insert into course(id, name, created_date, last_updated_date) 
values(10002, 'JDBC in 10 steps', LOCALTIMESTAMP, LOCALTIMESTAMP);
insert into course(id, name, created_date, last_updated_date) 
values(10003, 'JPQL in 50 steps', LOCALTIMESTAMP, LOCALTIMESTAMP);

insert into passport(id, number)
values(40001,'E12345');
insert into passport(id, number)
values(40002,'F212345');
insert into passport(id, number)
values(40003,'GE23451');

insert into student(id, name, passport_id)
values(20001,'Ranga',40001);
insert into student(id, name, passport_id)
values(20002,'Adam',40002);
insert into student(id, name, passport_id)
values(20003,'Jane',40003);

insert into review(id, rating, description, course_id)
values(50001,'1', 'Great course', 10001);
insert into review(id, rating, description, course_id)
values(50002,'3', 'Nice course', 10001);
insert into review(id, rating, description, course_id)
values(50004,'5', 'Good you are writing', 10003);

insert into student_course(student_id, course_id)
values(20001, 10001);
insert into student_course(student_id, course_id)
values(20002, 10001);
insert into student_course(student_id, course_id)
values(20003, 10001);
insert into student_course(student_id, course_id)
values(20001, 10003);



				
			
				
					package com.brains.jpa.hibernate.jpahibernatedemo;

import static org.junit.jupiter.api.Assertions.*;

import java.util.List;

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import com.brains.jpa.hibernate.jpahibernatedemo.entity.Course;
import com.brains.jpa.hibernate.jpahibernatedemo.entity.Student;

import jakarta.persistence.EntityManager;
import jakarta.persistence.TypedQuery;
import jakarta.transaction.Transactional;

@SpringBootTest(classes = JpaHibernateDemoApplication.class)
class JPQLQueryTest {

	private Logger logger = LoggerFactory.getLogger(getClass());
	
	@Autowired
	EntityManager em;
	
	// get course which do not have any student
//	@Test
	@Transactional
	void jpql_courses_without_students() {
		TypedQuery<Course> createQuery = em.createQuery("select c from Course c where c.students is empty", Course.class);
		List<Course> resultList = createQuery.getResultList();
		logger.info("Courses: -> {}", resultList);
	}
	
	// get courses where which has more thatn 2 students
//	@Test
	@Transactional
	void jpql_courses_with_atleast_2_students() {
		TypedQuery<Course> createQuery = em.createQuery("select c from Course c where size(c.students) > 2", Course.class);
		List<Course> resultList = createQuery.getResultList();
		logger.info("Courses: -> {}", resultList);
	}
	
	// get courses order by student size
	// by default, order by is ascending(0-10)
//	@Test
	@Transactional
	void jpql_courses_ordered_by_students() {
		TypedQuery<Course> createQuery = em.createQuery("select c from Course c order by size(c.students) desc", Course.class);
		List<Course> resultList = createQuery.getResultList();
		logger.info("Courses: -> {}", resultList);
	}
	
	// get students whose passport number contains 12345
	/**
	 * Other functions
	 * ===============
	 * like
	 * Between 100 and 500
	 * Is Null
	 * 
	 * ---- On String ------
	 * upper, lower, trim, length
	 */
	@Test
	@Transactional
	void jpql_sudent_passport_matching() {
		TypedQuery<Student> createQuery = em.createQuery("select s from Student s where s.passport.number like '%1234%'", Student.class);
		List<Student> resultList = createQuery.getResultList();
		logger.info("Courses: -> {}", resultList);
	}

}

				
			

Related Tutorials

Collection sort

Sort collection using stream and Lambda functions.

				
					import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class Sorter1 {
	public static void main(String[] args) {
		List<Student> students = new ArrayList<>();
		students.add(new Student("A", 10));
		students.add(new Student("B", 12));
		students.add(new Student("C", 8));
		students.add(new Student("D", 9));
		students.add(new Student("E", 11));
		students.add(new Student("F", 14));
		
		System.out.println("=== Before Sort ============");
		students.forEach(i -> System.out.println(i.toString()));
		
		List<Student> list1 = students.stream().sorted(Comparator.comparing(Student::getAge)).collect(Collectors.toList());
				// OR
		List<Student> list1 = students.stream().sorted((a,b) -> a.getAge().compareTo(b.getAge())).collect(Collectors.toList());
		
		System.out.println("\n=== After Sort ============");
		list1.forEach(i -> System.out.println(i.toString()));
	}
}
				
			

Sort collection without stream.

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

public class Sorter1 {
	public static void main(String[] args) {
		List<Student> students = new ArrayList<>();
		students.add(new Student("A", 10));
		students.add(new Student("B", 12));
		students.add(new Student("C", 8));
		students.add(new Student("D", 9));
		students.add(new Student("E", 11));
		students.add(new Student("F", 14));
		
		System.out.println("=== Before Sort ============");
		students.forEach(i -> System.out.println(i.toString()));
		
		students.sort(Comparator.comparing(Student::getAge));
		// OR
		students.sort((a,b)->a.getAge().compareTo(b.getAge()));
		
		System.out.println("\n=== After Sort ============");
		students.forEach(i -> System.out.println(i.toString()));
	}
}
				
			
				
					class Student{
	private String name;
	private Integer age;
	
	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}
	public String toString() {
		return this.name+" : "+ this.age;
	}
	public String getName() {
		return name;
	}
	public Integer getAge() {
		return age;
	}
}

				
			
				
					=== Before Sort ============
A : 10
B : 12
C : 8
D : 9
E : 11
F : 14

=== After Sort ============
C : 8
D : 9
A : 10
E : 11
B : 12
F : 14
				
			

Invoke SQL script during servlet initialization



Here MyContextListener is a listener which implements ServletContextListener

				
					--- web.xml ---

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app id="WebApp_ID">
	<display-name>proj2</display-name>
	
	<context-param>
		<param-name>createTables</param-name>
		<param-value>yes</param-value>
	</context-param>
	<listener>
		<listener-class>com.brains.MyContextListener</listener-class>
	</listener>
	<listener>
		<listener-class>com.brains.MySessionListener</listener-class>
	</listener>
	
	<servlet>
		<servlet-name>FirstServlet</servlet-name>
		<display-name>FirstServlet</display-name>
		<description></description>
		<servlet-class>brains.FirstServlet</servlet-class>
	</servlet>
	<servlet>
		<servlet-name>Login</servlet-name>
		<display-name>Login</display-name>
		<description></description>
		<servlet-class>brains.Login</servlet-class>
	</servlet>
	<servlet>
		<servlet-name>MyConfigDemo</servlet-name>
		<display-name>MyConfigDemo</display-name>
		<description></description>
		<servlet-class>brains.MyConfigDemo</servlet-class>
		<init-param>
			<param-name>driver</param-name>
			<param-value>com.mysql.jdbc.Driver</param-value>
			<description></description>
		</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>FirstServlet</servlet-name>
		<url-pattern>/FirstServlet</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>Login</servlet-name>
		<url-pattern>/login</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>MyConfigDemo</servlet-name>
		<url-pattern>/MyConfigDemo</url-pattern>
	</servlet-mapping>
	<welcome-file-list>
		<welcome-file>login.html</welcome-file>
	</welcome-file-list>
</web-app>

				
			
				
					package com.brains;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import brains.DBInitializer;

public class MyContextListener implements ServletContextListener {
    public MyContextListener() {
    	System.out.println("MyContextListener constructor");
    }
    public void contextDestroyed(ServletContextEvent sce)  { 
    	System.out.println("Context destroyed");
    }
    public void contextInitialized(ServletContextEvent sce)  { 
    	System.out.println("Context initialized");
    	ServletContext servletContext = sce.getServletContext();
    	String param = servletContext.getInitParameter("createTables");
    	if(param.equals("yes")) {
    		String table = servletContext.getRealPath("WEB-INF/table/table.sql");
    		System.out.println("img: "+ table);
    		
    		DBInitializer db = new DBInitializer();
    		db.createTables(table);
    	}
    }
}

				
			
				
					package brains;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DatabaseConnection {

	public static Connection initialize() throws SQLException, ClassNotFoundException {
		String dbDriver = "com.mysql.cj.jdbc.Driver";
		String dbUrl = "jdbc:mysql://localhost:3307/";
		
		String dbName = "servlet-demo";
		String dbUsername = "root";
		String dbPassword = "root";
		
		Class.forName(dbDriver);
		Connection con = DriverManager.getConnection(dbUrl+dbName,dbUsername, dbPassword);
		return con;
	}
}

				
			
				
					package brains;

import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.Statement;
import java.util.StringTokenizer;

public class DBInitializer {

	public void createTables(String path) {
		try {
			FileInputStream in = new FileInputStream(path);
			byte data[] = new byte[in.available()];
			in.read(data);
			in.close();
			StringTokenizer str = new StringTokenizer(new String(data), "/");
			Connection con = DatabaseConnection.initialize();
			Statement stmt = con.createStatement();
			System.out.println("Creating tables...");
			while(str.hasMoreElements()) {
				String qr = str.nextToken();
				System.out.println(qr);
				if(qr.trim().equals("stop")) {
					break;
				}
				stmt.execute(qr);
			}
			System.out.println("tables successfully created.");
		}catch(Exception e) {
			System.out.println(e);
		}
	}
	
}

				
			
				
					package brains;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class FirstServlet
 */
public class FirstServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public FirstServlet() {
        super();
        // TODO Auto-generated constructor stub
        System.out.println("constructor");
    }

//	@Override
//	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//		// TODO Auto-generated method stub
//		resp.getWriter().print("Servlet by http");
//	}

//	@Override
//	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
//		// TODO Auto-generated method stub
//		res.getWriter().print("Servlet by original service");
//	}
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
		resp.getWriter().print("Servlet by doGet");
		
		ServletConfig config = this.getServletConfig();
		ServletContext context = this.getServletContext();
		
		ServletContext servletContext = config.getServletContext();
		System.out.println(config);
		System.out.println(context);
		System.out.println(servletContext);
		
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		PrintWriter writer = resp.getWriter();
		
		String name = req.getParameter("name");
		String email = req.getParameter("email");
		String mobile = req.getParameter("mobile");
		String password = req.getParameter("password");
		
		Connection con = null;
		try {
			con = DatabaseConnection.initialize();
			PreparedStatement psc = con.prepareStatement("insert into employee values(?,?,?,?)");
			psc.setString(1, name);
			psc.setString(2, email);
			psc.setString(3, mobile);
			psc.setString(4, password);
			
			int i = psc.executeUpdate();
			if(i > 0) {
				resp.sendRedirect("welcome.html");
			}else {
				writer.println("problem");
			}
			
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

				
			
				
					package brains;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyConfigDemo extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		String dir = System.getProperty("user.dir");
		System.out.println("Dir: "+ dir);
		
//		String table = System.getProperty("user.dir")+"/table.sql";
		
		
		response.getWriter().println(this.getServletConfig());
		String name = (String) getServletContext().getAttribute("name");
		String password = (String) getServletContext().getAttribute("password");
		System.out.println("get: "+ name +":" + password);
		response.getWriter().println(name +" : "+password);
		
		
		ServletConfig config = this.getServletConfig();
		System.out.println(config);
		String driver = config.getInitParameter("driver");
		System.out.println("driver: "+ driver);
		
		ServletContext context = this.getServletContext();
		
		ServletContext servletContext = config.getServletContext();
		System.out.println(context);
		System.out.println(servletContext);
		
		String abcd = context.getInitParameter("abcd");
		System.out.println("abcd: "+ abcd);
		
		Enumeration<String> params = context.getInitParameterNames();
		while(params.hasMoreElements()) {
			String element = params.nextElement();
			System.out.println("element: "+ element +":"+context.getInitParameter(element));
		}
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		resp.getWriter().println(this.getServletConfig());
		
		String name = req.getParameter("name");
		String password = req.getParameter("password");
		System.out.println("post: "+ name +":" + password);
		resp.getWriter().println(name +" : "+password);
		
		
	}

}

				
			
				
					package brains;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Servlet implementation class Login
 */
public class Login extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		response.setContentType("text/html");
		String name = request.getParameter("name");
		String password = request.getParameter("password");
		
		ServletContext servletContext = this.getServletContext();
		servletContext.setAttribute("name", name);
		servletContext.setAttribute("password", password);
		
		try {
			Connection conn = DatabaseConnection.initialize();
			PreparedStatement ps = conn.prepareStatement("select * from employee where name = ? and password = ?");
			ps.setString(1, name);
			ps.setString(2, password);
			
			ResultSet rs = ps.executeQuery();
			if(rs.next()) {
				
				HttpSession session = request.getSession();
				response.sendRedirect("MyConfigDemo");
			}else {
				response.getWriter().println("<span style='color:red'>404 error</span>");
				RequestDispatcher rd = request.getRequestDispatcher("login.html");
				rd.include(request, response);
			}
			
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

				
			
				
					CREATE TABLE employee (
    name varchar(255),
    email varchar(255),
    mobile varchar(255),
    password varchar(255)
)
/
CREATE TABLE persons (
    lastName varchar(255),
    firstName varchar(255),
    address varchar(255),
    city varchar(255)
)
				
			
				
					<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body bgcolor="yellow">
<h2>Login here </h2>
<form action="login" method="post">
	<input type="text" placeholder="First name" name="name"/></br>
	<input type="text" placeholder="Password" name="password"/></br>
	<input type="submit" value="Login"/>
</form></br>
<a href="register.html">Register here</a>
</body>
</html>
				
			
				
					<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body bgcolor="yellow">
It works
<form action="FirstServlet" method="post">
	<input type="text" placeholder="First name" name="name"></br>
	<input type="text" placeholder="Email" name="email"></br>
	<input type="text" placeholder="Mobile" name="mobile"></br>
	<input type="text" placeholder="Password" name="password"></br>
	<input type="submit">
</form></br>
<a href="login.html">Login here</a>
</body>
</html>
				
			
				
					<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>Welcome</h2>
</body>
</html>
				
			

Servlet basics

Servlet is created using these 3 methods:

  • extends HttpServlet
  • implement Servlet
  • extends GenericServlet
 
 
Container is available inside of the server.
Container is the runtime environment of any component. Servlets run inside the Container.
 
Servlet lifecycle methods
  • init
  • service
  • destroy
web.xml also called Deployment Descriptor

Forward the response and request to other servlets

				
					RequestDispatcher rd = request.getRequestDispatcher("MyConfigDemo");
				rd.forward(request, response);
				
			
Home folder
				
					String dir = System.getProperty("user.dir");
System.out.println("Dir: "+ dir);
//Dir: /home/soundarya