Connecting a Spring Starter Project with MyBatis is not complicated. If you want to learn how to create a Spring Starter Project, please refer to my last post linked below.

https://www.agilemeadow.com/entry/Spring-Boot-Basics-of-Spring-Boot-Lombok

 

Spring Boot) Basics of Spring Boot /Lombok

What is Spring Boot? Spring Boot is an extension of Spring, which eliminates the boilerplate configurations required for setting up a Spring application. Features Spring Boot enables the development of independent running spring applications because Tomcat

www.agilemeadow.com

 

To connect MyBatis with Spring Boot, we must create a table. 

Create a sql file in webapp/ sql and create a table and sequence. 

create table boardtest(
		no number primary key,
		name varchar2(20),
		subject varchar2(50),
		content varchar2(1000),
		register date
);
create sequence boardtest_seq;

select * from tab;
select * from seq;

 

Configuration

The biggest difference between Spring and Spring Boot is configuration files. Spring has six configuration files, whereas, Spring Boot has four. 

 

The configuration has to be done in main/resource/application.properties.

# port 
server.port=80

# view resolver
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

# oracle
spring.datasource.driverClassName=oracle.jdbc.driver.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:xe
spring.datasource.username=spring
spring.datasource.password=spring123

# mybatis
mybatis.config-location=classpath:mybatis-config.xml
mybatis.mapper-locations=classpath:mapper/*.xml

After setting the location of the view files, create WEB-INF and views folders.

 

Create folders for each roles. 

In the folders, you will put these classes: 

config - database connection class

controller - controller class

dao - DAO class

model - DTO class

service - service class

 

DataAccessConfig.java

package com.example.demo.config;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

@Configuration
@PropertySource("classpath:/application.properties")          
public class DataAccessConfig {
	
	@ConfigurationProperties(prefix = "spring.datasource")    
	public DataSource dataSource() {
		return DataSourceBuilder.create().build();
	}
	
	@Bean
	public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception{
		SqlSessionFactoryBean factoryBean=new SqlSessionFactoryBean();
		
		factoryBean.setDataSource(dataSource);
		factoryBean.setMapperLocations(
				new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/*.xml")
				);
		factoryBean.setTypeAliasesPackage("com.example.demo.model"); // DTO Alias 설정
		return factoryBean.getObject();
	}
	
	@Bean
	public SqlSessionTemplate sessionTemplate(SqlSessionFactory sqlSessionFactory) {
		return new SqlSessionTemplate(sqlSessionFactory);
	}
}

board.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="boardns">

	<insert id="insert" parameterType="board"> 
		insert into boardtest values(boardtest_seq.nextval,#{name},#{subject},#{content},sysdate)
	</insert>
	
	<select id="list" resultType="board">
		select * from boardtest
	</select>
    </mapper>

 

Now, it is all set. What you are going to do is to create your project by yourself. 

 

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<script>
	location.href="boardform";
</script>

</body>
</html>

BoardController.java

	@RequestMapping("boardform")
	public String main() {
		System.out.println("controller in");
		return "boardform";
	}

boardform.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>New Post</title>
</head>
<body>
<form method="post" action="boardInsert">
<table border=1 align=center width=500>
	<caption>New Post</caption>
	<tr>
		<td>Writer</td>
		<td><input type=text name="name"></td>
	</tr>
	<tr>
		<td>Title</td>
		<td><input type=text name="subject"></td>
	</tr>
	<tr>
		<td>Content</td>
		<td><textarea cols="50" rows="5" name="content"></textarea></td>
	</tr>
	<tr>
		<td colspan=2 align="center">
			<input type=submit value="Submit">
			<input type=reset value="Cancel">
		</td>
	</tr>
</table>
</form>
</body>
</html>

boardlist.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>     
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Post List</title>
</head>
<body>
<a href="boardform">New Post</a> <br>
<table border=1 align=center width=800>
	<caption>Post List</caption>
	<tr>
		<th>No.</th>
		<th>Writer</th>
		<th>Title</th>
		<th>Date</th>
		<th>Content</th>
	</tr>	
	<c:forEach var="b" items="${list }">
	<tr>
		<td>${b.no}</td>
		<td>${b.name}</td>
		<td>${b.subject}</td>
		<td>
			<fmt:formatDate value="${b.register}" pattern="yyyy-MM-dd HH:mm:ss"/>
		</td>
		<td>${b.content}</td>
	</tr>
	</c:forEach>	
</table>
</body>
</html>

 

 

Thymeleaf is a template engine that plays a key role in web frameworks, though, and is one of its most important components as they are in charge of producing the user interface or view layer (usually in XHTML or HTML form).

 

Here is a very nice article that you can refer to for introducing yourself to the Thymeleaf world. 

In this post, we will see the basic syntaxes of Thymeleaf.

https://www.baeldung.com/thymeleaf-in-spring-mvc

 

 

First, you must write this tag to use the thymeleaf tags in the HTML or XHTML. 

<html xmlns:th="http://www.thymeleaf.org">

And, save the objects in a controller class and call with the thymeleaf tags. 

SampleController.java 

package com.example.demo.controller;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.example.demo.model.Member;

@Controller
public class SampleController {

	@RequestMapping("sample1")
	public String sample1(Model model) {		
//		model.addAttribute("greeting", "Hello World");
		model.addAttribute("greeting", "Hello World");		
		return "sample1";
	}
	
	@RequestMapping("sample2")
	public String sample2(Model model) {
		Member member = new Member(1,"test","1234","Meadow", new Timestamp(System.currentTimeMillis()));
		
		model.addAttribute("member", member);
		
		return "sample2";
	}
	
	@RequestMapping("sample3")
	public String sample3(Model model) {
		List<Member> list = new ArrayList<Member>();
		
		for(int i=0; i<10; i++) {
			Member member = new Member(1,"test"+i,"1234","Meadow"+i, new Timestamp(System.currentTimeMillis()));			
			list.add(member);
		}		
		model.addAttribute("list", list);
		
		return "sample3";
	}
	
	@RequestMapping("sample4")
	public String sample4(Model model) {
		List<Member> list = new ArrayList<Member>();
		
		for(int i=0; i<10; i++) {
			Member member = new Member(i,"u000"+i %3,     // 3으로 나눈 나머지 id
					                     "p000"+i %3,     // 3으로 나눈 나머지 pw 
					                     "Meadow"+i, 
					                     new Timestamp(System.currentTimeMillis()));			
			list.add(member);
		}		
		model.addAttribute("list", list);
		
		return "sample4";
	}
	
	@RequestMapping("sample5")
	public String sample5(Model model) {
		
		String result = "SUCCESS";
		
		model.addAttribute("result", result);
		
		return "sample5";
	}
	
	@RequestMapping("sample6")
	public String sample6(Model model) {	
		
		model.addAttribute("now", new Date());
		model.addAttribute("price", 123456789);
		model.addAttribute("title", "Sample title");
		model.addAttribute("options", Arrays.asList("AAA","BBB","CCC","DDD"));
		
		return "sample6";
	}
	
	@RequestMapping("sample7")
	public String sample7(Model model) {	
		
		return "sample7";
	}
	
}

 

To print out String : th:text

<h1 th:text="${greeting}">Thymeleaf Test page</h1>

If you just write ${greeting}, it will not work as a thymeleaf tag. 

 

To print DTO object : th:text

<h1 th:text="${member}">Thymeleaf Test page</h1>

To print out the data from the controller class : th:utext

<div th:utext='${"<h3>"+member.no+"</h3>"}'></div> 
<div th:utext='${"<h3>"+member.id+"</h3>"}'></div> 
<div th:utext='${"<h3>"+member.pw+"</h3>"}'></div> 
<div th:utext='${"<h3>"+member.name+"</h3>"}'></div> 
<div th:utext='${"<h3>"+member.regdate+"</h3>"}'></div>

To print out list object : the:each="member : ${list}"

	<tr th:each="member : ${list}">
		<td th:text="${member.id}"></td>
		<td th:text="${member.name}"></td>
		<td th:text="${#dates.format(member.regdate,'yyyy-MM-dd HH:mm:ss')}"></td>
	</tr>

To run loops : th:each

<table border="1" align="center" width="300">
	<tr>
		<td>ID</td>
		<td>NAME</td>
		<td>REGDATE</td>
	</tr>
	<tr th:each="member : ${list}">
		<td th:text="${member.id}"></td>
		<td th:text="${member.name}"></td>
		<td th:text="${#dates.format(member.regdate,'yyyy-MM-dd HH:mm:ss')}"></td>
	</tr>
</table><br>

To define variables : th:with

<table border="1" align="center" width="300" th:with="target='u0001'">

If tag : th:if ~ th:unless

<table border="1" align="center" width="300" th:with="target='u0001'">
	<tr>
		<td>ID</td>
		<td>NAME</td>
		<td>REGDATE</td>
	</tr>
    
	<tr th:each="member : ${list}">
		<td th:if="${member.id}">
		    <a href="/modify" th:if="${member.id == target}">Modify</a>
		    <p th:unless="${member.id == target}">View</p>
		</td>
		<td th:text="${member.name}"></td>
		<td th:text="${#dates.format(member.regdate,'yyyy-MM-dd HH:mm:ss')}"></td>
	</tr>
</table>

To run javascript with thymeleaf : th:inline

<script th:inline="javascript">
	var result = [[${result}]]; 	   
	document.write(result);			
</script>

<script>
	var result = [[${result}]];          
	document.write(result);              
</script>

To set the format of dates

<h2 th:text="${#dates.format(now, 'yyyy-MM-dd HH:mm:ss')}"></h2>

To set the format of numbers

<h2 th:text="${#numbers.formatInteger(price, 3, 'COMMA')}"></h2>

To print out bold

<span th:utext="${#strings.replace(title,'t','<b>t</b>')}"></span>

To break down into words and print out as a list (parsing)

<ul>
	<li th:each="str:${#strings.listSplit(title,' ')}">[[${str}]]</li>
</ul>

 

To link 

<ul>    
	<li><a th:href="@{http://localhost:80/sample1}">sample1</a></li>
	<li><a th:href="@{/sample1}">sample1</a></li>
	<li><a th:href="@{~/sample1}">sample1</a></li>
	
	<!-- To send the value -->	
	<!-- http://localhost/Thymeleaf/sample1?p1=aaa&p2=bbb -->
	<li><a th:href="@{/sample1(p1='aaa', p2='bbb')}">sample1</a></li>
</ul>

To print out list with for loop

HomeController.java

package com.example.demo.controller;

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

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

@Controller
public class HomeController {

	
	@RequestMapping("/listTest")
	public void listTest(Model model) {
		
		List list = new ArrayList();
		
		for(int i=1; i<=20; i++) {
			list.add("Data:"+i);
		}
		
		model.addAttribute("name", "Sample Data");
		model.addAttribute("list", list);
	}
}

listTest.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Thymeleaf Example</title>
</head>
<body>

	<p th:text=" 'Hello, ' + ${name} +'!' "/>
	
	<ul>
		<li th:each="data : ${list}"  th:text="${data}"></li>
	</ul>

</body>
</html>

 

What is Spring Boot? Spring Boot is an extension of Spring, which eliminates the boilerplate configurations required for setting up a Spring application.

 

Features

Spring Boot enables the development of independent running spring applications because Tomcat and Jetty are already embedded. It manages libraries with Maven/Gradle using Integrated Starter and provides automated spring settings which means you don't need six configuration files as Spring. 
Also, what makes it more convenient is that it does not require cumbersome XML settings. Spring Boot also provides Spring Actuator which is used for monitoring and managing applications. 

 

If you already have higher than STS3.0, you can easily create a Spring Boot Project. 

There are many dependencies that you can add easily such as websocket, NoSQL, SQL, MyBatis Framework, and so on. Here, check the Spring web box to add the dependency. 

Once we create the project, to check if it is created well, run it on the Spring Boot App.

If you see this on the console, it means it is set well! 

 

Configuration 

pom.xml 

configuration.xml

mapper class. 

 

There are no servlet-context.xml, root-context.xml, and web.xml.

In the static folder, we will save css related files and in the templates folder, we will save HTML files. 

In Spring Boot, you need to make controller classes by yourself, unlike Spring. So, create the controller folder in the demo folder, and create SampleController.java. 

 

The application.properties file is empty, you will add the basic configurations that you want to set such as a port number and prefix and suffix. Depending on the functions of the projects, you can add other properties in this file. Other then this, Spring and Spring Boot are very similar. 

 

Lombok 

Lombok is something that makes the project even simpler. Once you use Lombok function, you don't need getter and setter methods in DTO class. Instead of these methods, with this Lombok function, you can use simple annotations. 

 

To compare the projects with and without Lombok function, we will create a new project. 

 

Spring Starter Project without Lombok

Create a new project and check the boxes of the dependencies that you need for the project. 

The dependencies that you checked will be downloaded automatically once you click the Finish button and you will see the dependencies in pom.xml.

 

In application.properties, you won't see anything because, in Spring Boot, we need to add the configurations. 

So, we will set a port number and prefix/ suffix here.

 

In main / java / com / example / demo / model, create a DTO Class, Member.java

In this project, we are not using the Lombok, so we will create getter and setter methods. 

In the same demo folder, create a controller package and create SampleController.java.

Create index.jsp to connect the controller class. In the index.jsp, link "main" and create main.jsp.

 

In this demonstration, we will make a login form. 

main.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Log in</title>
</head>
<body>
	<form method="post" action="send">
	ID: <input type=text name="id"> <br>
	Password: <input type=text name="passwd"> <br>
	<input type="submit" value="Log in">
	</form>

</body>
</html>

So the flow will be index.jsp -> SampleController.java -> main.jsp.

In terms of encoding, you don't have to care, because Spring boot will automatically take care of it.

 

Spring Starter Project with Lombok

With the Lombok dependency, you don't have to create getter and setter methods, or other constructors like toString() and Equals(). First, add the dependency in pom.xml and we need to download the dependency from the Lombok website(https://projectlombok.org/all-versions).

To execute the downloaded file, you need to do two things: add dependency and install it in STS.

Since we already added the dependency, we will do the latter one. 

Open the command prompt and insert the commands below.

 

Click the Install/Update button and you will see the alert "Install successful".

It is all set and now, we can use the Lombok function. 

In the Member.java, comment out the getter and setter methods. 

Instead of getter and setter methods, we will use annotations. 

	@Getter
	@Setter
	// @Data
	public class Member {
		private String id;
		private String passwd;
	}

As you can see, if you use the Lombok function, the codes will be still shorter and simpler. 

2022.10.11 - [Spring] - Spring) How to start a new Spring Framework Project[1]

 

Spring) How to start a new Spring Framework Project[1]

Starting a new Spring Framework Project is similar to creating a Dynamic Web Project in Eclipse. However, the structure is a bit more complicated if it is your very first time. So in this post, we w..

www.agilemeadow.com

 

32. Create boardlist.jsp 

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Post List</title>
</head>
<body>
	<a href="boardform.do">New post</a>
	<br> Total posts: ${listcount }
	<table border=1 align=center width=700>
		<caption>Post list</caption>
		<tr>
			<th>No.</th>
			<th>Title</th>
			<th>Writer</th>
			<th>Date</th>
			<th>View Count</th>
		</tr>

		<!-- Post List -->
		<c:set var="num" value="${listcount - (page-1) * 10 }" />
		<c:forEach var="b" items="${boardlist}">
			<tr>
				<td>${num }<c:set var="num" value="${num-1 }" />
				</td>
				<td>
				<a href="boardcontent.do?no=${b.no }&page=${page}"/>
				${b.subject }
				</td>
				<td>${b.writer }</td>
				<td>
				<fmt:formatDate value="${b.register }"
					 pattern="dd-MM-yyyy HH:mm:ss"/>
				</td>
				<td></td>
			</tr>
		</c:forEach>
	</table>
	
	<!-- Pagination -->
	<center>
	<c:if test="${listcount > 0 }">
	
	<!-- Move to page no.1 -->
	<a href="boardList.do?page=1" style="text-decoration:none"> << </a>
	
	<!-- Move to the previous block -->
	<c:if test="${starPage > 10 }">
	<a href="boardlist.do?page=${startPage-1 }" style="text-decoration:none">[Prev]</a>
	</c:if>
	
	<!-- Print 10 posts in each block -->
	<c:forEach var="i" begin="${startPage }" end="${endPage }">
	<c:if test="${i == page }"> <!-- Current Page -->
	 [${i }]
	</c:if>
	
	<c:if test="${i != page }"> <!-- Not a current Page -->
	 <a href="boardlist.do?page${i}">[${i }]</a>
	</c:if>
	
	</c:forEach>
	
	<!-- Move to the next block -->
	<c:if test="${endPage < pageCount }">
	<a href="boardlist.do?page${startPage+10 }" style="text-decoration:none">[Next]</a>
	</c:if>
	
	<!--  Move to the last page -->
	<a href="boardlist.do?page${pageCount }" style="text-decoration:none"> >> </a>
	
	</c:if>
	</center>
	
</body>
</html>

33. In the controller class, add codes for the detail page. 

BoardController.java

// Post Detail : view count +1 , Post detail
		@RequestMapping("boardcontent.do")
		public String boardcontent(int no, int page, Model model) {
			
			//View count +1
			bs.updatecount(no);
			Board board = bs.getBoard(no);
			String content = board.getContent().replace("\n", "<br>");
			
			model.addAttribute("board", board);
			model.addAttribute("content", content);
			model.addAttribute("page", page);
			
			return "board/boardcontent";
		}

33. In the service class, connect it to the dao class.

BoardService.java

	public void updatecount(int no) {
		dao.updatecount(no);
	}

	public Board getBoard(int no) {
		return dao.getBoard(no);
	}

BoardDao.java

	public void updatecount(int no) {
		// TODO Auto-generated method stub
		session.update("hit", no);
	}

	public Board getBoard(int no) {
		// TODO Auto-generated method stub
		return session.selectOne("content", no);
	}

34. In the board.xml, add the update and select SQL.

	<!-- view count + 1 -->
	<update id="hit" parameterType="int">
		update myboard set readcount=readcount+1 where no=#{no}
	</update>
	
	<!-- Post detail -->
	<select id="content" parameterType="int" resultType="board">
		select * from myboard where no = #{no}
	</select>

35. Create boardcontent.jsp.

Link the List, Edit, and Delete buttons to corresponding pages. 

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Post detail</title>
</head>
<body>
	<table border=1 width=400 align=center>
		<caption>Post detail</caption>
		<tr>
			<td>Writer</td>
			<td>${board.writer }</td>
		</tr>
		<tr>
			<td>Date</td>
			<td><fmt:formatDate value="${board.register }"
					pattern="dd-MM-yyyy HH:mm:ss" /></td>
		</tr>
		<tr>
			<td>View</td>
			<td>${board.readcount }</td>
		</tr>
		<tr>
			<td>Title</td>
			<td>${board.subject }</td>
		</tr>
		<tr>
			<td>Content</td>
			<td><pre>${board.content }</pre> ${content}</td>
		</tr>
		<tr>
			<td colspan=2 align=center>
			<input type="button" value="List"
			onClick ="location.href='boardlist.do?page=${page}' ">
			<input type="button" value="Edit"
			onClick="location.href='boardupdateform.do?no=${board.no}&page=${page}'"> 
			<input type="button" value="Delete"
			onClick="location.href='boarddeleteform.do?no=${board.no }&page=${page}'">
			</td>
		</tr>

	</table>

</body>
</html>

36. In the controller class, we will request the values with @RequestMapping annotation

// Post Detail : view count +1 , Post detail
		@RequestMapping("boardcontent.do")
		public String boardcontent(int no, int page, Model model) {
			
			//View count +1
			bs.updatecount(no);
			Board board = bs.getBoard(no);
			String content = board.getContent().replace("\n", "<br>");
			
			model.addAttribute("board", board);
			model.addAttribute("content", content);
			model.addAttribute("page", page);
			
			return "board/boardcontent";
		}

37. Create boardupdateform.jsp and link the controller class to this file. 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Edit Post</title>
</head>
<body>

<form method=post action="boardupdate.do">
<input type="hidden" name="no" value="${board.no }">
<input type="hidden" name="page" value="${page }">
<table border=1 width=400 align=center>
	<caption>Edit Post</caption>
	<tr><th>Writer</th>
		<td><input type=text name="writer" required="required"
		value="${board.writer }" autofocus="autofocus"></td>
	</tr>
	<tr><th>Password</th>
		<td><input type=password name="passwd" required="required"></td>
	</tr>
	<tr><th>Title</th>
		<td><input type=text name="subject" required="required" value="${board.subject }"></td>
	</tr>
	<tr><th>Content</th>
		<td><textarea cols=40 rows=5 name="content" required="required">${board.content }</textarea></td>
	</tr>
	<tr><td colspan=2 align=center>
			<input type=submit value="Edit">
			<input type=reset value="Cancel">
		</td>
	</tr>
</table>
</form>

</body>
</html>

38. BoardController.java -> BoardService.java -> BoardDao.java

BoardController.java

//Update Form 
		@RequestMapping("boardupdateform.do")
		public String boardupdateform(int no, int page, Model model) {
			
			Board board = bs.getBoard(no);	//Detail 
			
			model.addAttribute("board", board);
			model.addAttribute("page", page);
			
			return "board/boardupdateform";
		}
		
		// Update
		@RequestMapping("boardupdate.do")
		public String boardupdate(Board board, int page, Model model) {
			int result = 0;
			Board old = bs.getBoard(board.getNo());
			
			// Password Check
			if(old.getPasswd().equals(board.getPasswd())) { //Correct Password
				result = bs.update(board);			// Update 
			}else {    										//Incorrect Password
				result = -1;
			}
			model.addAttribute("result", result);
			model.addAttribute("board", board);
			model.addAttribute("page", page);

			return "board/updateresult";
		}

BoardService.java 

	public int update(Board board) {
		// TODO Auto-generated method stub
		return dao.update(board);
	}

BoardDao.java

	public int update(Board board) {
		// TODO Auto-generated method stub
		return session.update("update", board);
	}

39. Insert update SQL in the board.xml.

<!-- Update -->
	<update id="update" parameterType="board">
		update myboard set writer=#{writer}, subject=#{subject}, 
		content=#{content}, register=sysdate where no=#{no}
	</update>

40. Create updateresult.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>updateresult</title>
</head>
<body>

	<c:if test="${result == 1 }">
		<script>
			alert("Successfully updated.");
			location.href ="boardlist.do?page=${page}"; //List page
			//	location.href="boardcontent.do?no=${board.no}&page=${page}";	//Detail page
		</script>
	</c:if>

	<c:if test="${result != 1 }">
		<script>
			alert("Failed to update.");
			history.go(-1);
		</script>
	</c:if>

</body>
</html>

41. Create boarddeleteform.jsp.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Delete Post</title>
</head>
<body>

no: ${param.no }<br>
page: ${param.page }<br>

<form method=post action="boarddelete.do">
<input type="hidden" name="no" value="${param.no }">
<input type="hidden" name="page" value="${param.page }">
<table border=1 width=400 align=center>
	<caption>Delete Post</caption>
	
	<tr><th>Password</th>
		<td><input type=password name="passwd" required="required"></td>
	</tr>
	<tr><td colspan=2 align=center>
			<input type=submit value="Delete">
			<input type=reset value="Cancel">
		</td>
	</tr>
</table>
</form>

</body>
</html>

42. Add the code in the BoardController.java -> BoardService.java -> BoardDao.java.

BoardController.java

		// Delete
		@RequestMapping("boarddelete.do")
		public String boarddelete(Board board, int page, Model model) {
			int result = 0;
			Board old = bs.getBoard(board.getNo());		// Post Detail
			
			//Password Check
			if(old.getPasswd().equals(board.getPasswd())) { //Correct Password
				result = bs.delete(board.getNo());			// Delete
			}else {    										//Incorrect Password
				result = -1;
			}
			
			model.addAttribute("result", result);
			model.addAttribute("page", page);
			
			return"board/deleteresult";
		}
}

BoardService.java

	public int delete(int no) {
		// TODO Auto-generated method stub
		return dao.delete(no);
	}

BoardDao.java.

	public int delete(int no) {
		// TODO Auto-generated method stub
		return session.delete("delete", no);
	}

43. Insert delete SQL in the board.xml.

	<!-- Delete -->
	<delete id="delete" parameterType="int">
		delete from myboard where no = #{no}
	</delete>

44. Create deleteresult.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Delete</title>
</head>
<body>
	<c:if test="${result == 1 }">
		<script>
			alert("Successfully deleted.");
			location.href = "boardlist.do?page=${page}";
		</script>
	</c:if>

	<c:if test="${result != 1 }">
		<script>
			alert("Failed to delete.");
			history.go(-1);
		</script>
	</c:if>

</body>
</html>

As you can see, once you get the pattern, it becomes easier to process more efficiently. 

Starting a new Spring Framework Project is similar to creating a Dynamic Web Project in Eclipse. However, the structure is a bit more complicated if it is your very first time. 

So in this post, we will discuss creating a spring project from scratch. 

 

Create a spring project on STS and a new account on Oracle. 

After then, create the folders and files.

 

Configuration file settings in order
1) pom.xml
2) web.xml
3) servlet-context.xml
4) configuration.xml
5) board.xml
6) root-context.xml

 

1. Create a new account 

2. Create a Spring Legacy Project.

Fill out the project name, and select the Spring MVC Project.

Write the top-level package in the reverse order of the normal website URLs. 

Once it is created, you will see this.

To see if it works, run it on the server.

You will see this on the Server.

3. Create sql folder and sql file. Connect to the new account. 

4. Create a new table and sequence. 

-- Bulletin board

select * from tab;
select * from seq;
select * from myboard;

create table myboard(
	  no number primary key,
	  writer varchar2(20),
      passwd varchar2(20),
	  subject varchar2(50),
	  content varchar2(100),
	  readcount number,
	  register date );

create sequence myboard_seq;

5. Set pom.xml and run on the server to see if it is set well.

6. Set web.xml. Include encoding tags. 

7. Set HomeController.java.

8. Create an index.jsp in webapp folder. Link to the "test.do".

You must keep testing the project every time you create a new file. 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<script>
	location.href="test.do";

</script>

</body>
</html>

9. Set servlet-context.xml. Set the base package as myspring and create a new myspring folder containing controller, dao, model, and service folders.

10. Make BoardController.java,BoardService.java, and BoardDao.java in each folder.

11. In the BoardController class, add @Controller, @Autowired annotations. Create the same annotations with other classes as below.

BoardService - @Service, @Autowired

BoardDao - @Repository, @Autowired

 

Please see the picture below to understand what to put in the classes.

12. Create Board.java in the model folder. 

package myspring.model;

import java.util.Date;

public class Board {
	
	private int no;
	private String writer;
	private String passwd;
	private String subject;
	private String content;
	private int readcount;
	private Date register;
	
	public int getNo() {
		return no;
	}
	public void setNo(int no) {
		this.no = no;
	}
	public String getWriter() {
		return writer;
	}
	public void setWriter(String writer) {
		this.writer = writer;
	}
	public String getPasswd() {
		return passwd;
	}
	public void setPasswd(String passwd) {
		this.passwd = passwd;
	}
	public String getSubject() {
		return subject;
	}
	public void setSubject(String subject) {
		this.subject = subject;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public int getReadcount() {
		return readcount;
	}
	public void setReadcount(int readcount) {
		this.readcount = readcount;
	}
	public Date getRegister() {
		return register;
	}
	public void setRegister(Date register) {
		this.register = register;
	}
	
}

13. Create a board folder in the views folder. In the board folder, create the first file, boardform.jsp.

14. Change the link in the index file to the "boardform.do".

15. In the controller class, connect the boardform.do with the @RequestMapping annotation.

// Boardform
		@RequestMapping("boardform.do")
		public String boardform() {
			return "board/boardform";
		}

16. Set configuration.xml.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

	<typeAliases>
		<typeAlias alias="board" type="myspring.model.Board" />
	</typeAliases>	
	
</configuration>

17. Create a mapper file, board.xml.

18. Set root-context.xml to connect to the database.

You need to keep this order of configuration files to make the project run. 

19. To insert the contents in the database, go to the controller class and add the codes to connect DAO Class.

BoardController.java

// Write a new post
		@RequestMapping("boardwrite.do")
		public String boardwrite(Board board, Model model) {
			int result = bs.insert(board);
			if(result == 1) System.out.println("Successfully posted.");
			
			model.addAttribute("result", result);
			
			return "board/insertresult";
		}

20. In the service class and DAO Class, add the insert() method

BoardService.java

public int insert(Board board) {
		return dao.insert(board);
	}

BoardDao.java

	public int insert(Board board) {
		return session.insert("insert", board);
	}

21. In the board.xml, add insert SQL. The parameter type, the board is the alias set in the configuration file. 

Do not put a semicolon after the SQL. 

<!-- New post -->
	<insert id="insert" parameterType="board"> 	<!-- board: Alias of Configuration.xml -->
		insert into myboard values(myboard_seq.nextval,#{writer},
		#{passwd}, #{subject}, #{content},0, sysdate)
	</insert>

22. Create a new file, insertresult.jsp.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
    
<c:if test="${result == 1 }">
	<script>
		alert("Successfully posted.");
		location.href="boardlist.do";
	</script>
</c:if>

<c:if test="${result != 1 }">
	<script>
		alert("Failed to post");
		history.go(-1);
	</script>
</c:if>

23. Add codes in the controller class to see the post list. Also, include the codes for pagination. 

		// Post list & pagination
		@RequestMapping("boardlist.do")
		public String boardlist(HttpServletRequest request, Model model) {
			
			int page = 1;  // current page no. 
			int limit = 10;  // limit posts on the page 
			
			if(request.getParameter("page") != null) {
				page = Integer.parseInt(request.getParameter("page"));
			}
			
			int startRow = (page - 1) * limit + 1;
			int endRow = page * limit;
			
			int listcount = bs.getCount(); // Total data count 
			System.out.println("listcount: " + listcount);
			
			List<Board> boardlist = bs.getBoardList(page); // Post List
			System.out.println("boardlist:" + boardlist);

24. In the service class and the DAO class, add the getCount() method.

BoardService.java

	public int getCount() {
		return dao.getCount();
	}

BoardDao.java

	public int getCount() {
		return session.selectOne("count");
	}

25. Add select SQL in the board.xml.

26. Edit the index.jsp. 

location.href="boardlist.do";

27. In the BoardController.java, add the code showing the post list. 

28. In the Service class and the DAO class, ass the List part. 

BoardService.java

	public List<Board> getBoardList(int page) {
		return dao.getBoardList(page);
	}

BoardDao.java

	public List<Board> getBoardList(int page) {
		return session.selectList("list", page);
	}

29. Add the list id in the board.xml.

 You can use &gt; / &lt; means "greater than"/ "less than" in xml files which has the same role as the <![CDATA[]]>.

<!--  Post list -->
	<select id="list" parameterType="int" resultType="board">
		<![CDATA[
		select * from (select rownum rnum, board.* from (
		select * from myboard order by no desc) board )
		where rnum >= ((#{page}-1) * 10 + 1) and rnum <= (#{page} * 10)
		]]>
	</select>

30. Add the codes in the Controller class for the start and end pages.

// Total page
			int pageCount = listcount / limit + ((listcount%limit == 0)? 0 : 1);
			
			int startPage = ((page - 1) / 10) * limit + 1; //1, 11, 21,..
			int endPage = startPage + 10 - 1;			  //10, 20, 30..
			
			if(endPage > pageCount) endPage = pageCount;
			
			model.addAttribute("page", page);
			model.addAttribute("listcount", listcount);
			model.addAttribute("boardlist", boardlist);
			model.addAttribute("startPage", startPage);
			model.addAttribute("endPage", endPage);
			
			
			return "board/boardlist";
		}

31. To demonstrate, insert the data on Oracle. 

insert into myboard values(myboard_seq.nextval, 'Meadow', '111', 'Spring & MyBatis', 'Bulletin Board Project',0,sysdate);

 

Continue in the next post.

To demonstrate, I did a project. There is no Data Source Management in STS, so we will add the plug-in. 

Check this figure out to understand the Spring Framework structure with MyBatis.

 

The first file that you need to set is pom.xml. This is for the configuration, so you must add the dependencies to use the libraries in the project. 

Next, we need to take care of is web.xml. There are three excellent contents: the location of the servlet class, the servlet mapping, the connection to the servlet-context.xml, and UTF-8 encoding.

 

<servlet-class> and <servlet-mapping>

root-context.xml and servlet-context.xml

encoding : UTF-8

In the servlet-context.xml, you will see the base-package is myBatis1, and the root-context.xml is for database connection. In this file that I am demonstrating, there is nothing much in the root-context.xml, but 

 

In the DeptDaoImpl.java, you will see the @Autowired annotation. This @Autowired annotation is for injecting the SQLs. 

 

In the resources directory, there are configuration files. 

In the configuration.xml, you will see three like the ones below. 

 

<typeAlias>

<property>

<mapper resource>

This project needs six configuration files: pom.xml, web.xml, servlet-context.xml, root-context.xml, and configuration.xml.

 

Compare the mapper class in the Spring to the average MyBatis Model2 Mapper Class; it is way more straightforward in the Spring Framework. From Model2, when we print out the result, we use EL(Expression Language). 

 

Spring Mapper Class

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="deptns">
	
	<!-- Use type aliases to avoid typing the full classname every time. -->
	<resultMap id="deptResult"    type="dept">
		<result property="deptno" column="deptno" />
		<result property="dname"  column="dname" />
		<result property="loc"	  column="loc" />
	</resultMap>
	
	<select id="list" resultMap="deptResult">
		select * from dept order by deptno
	</select>
	
	<select id="select" parameterType="int" resultType="dept">
		select * from dept where deptno=#{deptno}
	</select>
	
	<update id="update" parameterType="dept">
		update dept set dname=#{dname},loc=#{loc} where deptno=#{deptno}
	</update>
	
	<delete id="delete" parameterType="int">
		delete from dept where deptno=#{deptno}
	</delete>
	
</mapper>

 

MyBatis Model2 Mapper Class

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="mymember">


	<insert id="insert" parameterType="member">
	  insert into member0609 values(#{id},#{passwd},#{name},#{jumin1},#{jumin2},
	  #{mailid},#{domain},#{tel1},#{tel2},#{tel3},#{phone1},#{phone2},#{phone3},
	  #{post},#{address},#{gender},#{hobby},#{intro},sysdate)
	</insert>
	

	<select id="idcheck" parameterType="String" resultType="member">
	 select * from member0609 where id = #{id}
	</select>
	

	<update id="update" parameterType="member">
	  update member0609 set name=#{name}, jumin1=#{jumin1}, jumin2=#{jumin2}, 
	  mailid=#{mailid}, domain=#{domain}, tel1=#{tel1}, tel2=#{tel2}, tel3=#{tel3},
	  phone1=#{phone1}, phone2=#{phone2}, phone3=#{phone3}, post=#{post}, address=#{address},
	  gender=#{gender}, hobby=#{hobby}, intro=#{intro} where id = #{id}
	</update>


	<delete id="delete" parameterType="String">
	  delete from member0609 where id = #{id}
	</delete> 

</mapper>

 

 

 

In the configuration files, especially servlet-context.xml, you will see the interceptor settings like this:

Spring Interceptors are used to intercept client requests and process them. Sometimes we want to intercept the HTTP Request and do some processing before handing it over to the controller handler methods.(Digital Ocean)

There are two ways to run interceptors: Inheriting abstract class HandlerInterceptorAdapter Class, or Inheriting interface HandlerInterceptor Interface

 

Let's take a look at this LoginCheck.java.

LoginCheck.java

package com.ch.ch07;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class LoginCheck implements HandlerInterceptor {
	
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
	}

	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
	}

	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
		HttpSession session = request.getSession();
		if (session.getAttribute("id") == null) {
			response.sendRedirect("loginForm.do");
			return false;
		}
		return true;
	}
}

In this class, we are using the latter way. Here, we are only using preHandle method, which is needed between the Dispatcher Servlet class and the Controller class.

In the if statement in preHandle method, it will load to the loginForm if there is no session. 

LoginForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ include file="header.jsp"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<div class="container">
		<form action="login.do">
			<h2 class="text-primary">Log In</h2>
			<c:if test="${not empty msg }">
				<span class="err">${msg }</span>
			</c:if>
			<table class="table table-bordered">
				<tr>
					<th>ID</th>
					<td><input type="text" name="id" required="required"></td>
				</tr>
				<tr>
					<th>Password</th>
					<td><input type="password" name="pass" required="required"></td>
				</tr>
				<tr>
					<th colspan="2"><input type="submit" value="확인"></th>
				</tr>
			</table>
		</form>
	</div>
</body>
</html>

If you write the wrong ID or Password, it will load to @RequestMapping("login.do") and print out "Incorrect ID or Password."

UploadController.java

package com.ch.ch07;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.servlet.http.HttpSession;

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.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

@Controller
public class UploadController {
	@RequestMapping(value = "upload.do", method = RequestMethod.GET)
	public String uploadForm() {
		return "upload";
	}

	@RequestMapping(value = "upload.do", method = RequestMethod.POST)
	public String upload(@RequestParam("file") MultipartFile mf, Model model, HttpSession session)
			throws IllegalStateException, IOException {
		String fileName = mf.getOriginalFilename();
		int fileSize = (int) mf.getSize();
		// mf.transferTo(new File("/gov/"+fileName));
		String path = session.getServletContext().getRealPath("/upload");
		FileOutputStream fos = new FileOutputStream(path + "/" + fileName);
		fos.write(mf.getBytes());
		fos.close();
		
		model.addAttribute("fileName", fileName);
		model.addAttribute("fileSize", fileSize);
		return "uploadResult";
	}

	@RequestMapping("loginForm.do")
	public String loginForm() {
		return "loginForm";
	}

	@RequestMapping("login.do")
	public String login(String id, String pass, HttpSession session, Model model) {
		if (id.equals("java") && pass.equals("1234")) {
			session.setAttribute("id", id);
			return "loginSuccess";
		} else {
			model.addAttribute("msg", "Incorrect ID or Password");
			return "loginForm";
		}
	}
}

When you write the correct ID and Password, you will see this. 

 

Knowing which files are in which folder is crucial since the structure is more complex than other projects and we have to know where to put the correct files. 

When you run the program, the web.xml file will be the first to read. There are basic settings in the web.xml.

Let's take a look at web.xml.

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	<!-- Language Encoding -->
	<filter>
		<filter-name>CharacterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!-- The definition of the Root Spring Container shared by all Servlets 
		and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/root-context.xml</param-value>
	</context-param>
	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>

<servlet-name> is appServlet, and we can set or change the pattern. 

<filter> and <filter-mapping> is for encoding Korean values into UTF-8 with the post method. Once you set the encoding here in the web.xml, you don't need to set the encoding in the other files. If the language you or your company use is not English, you always have to take care of encoding, but with Spring, it is the only thing you need to do. 

web.xml is connected to servlet-context.xml and root-context.xml. 

servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />
	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />
	<resources mapping="/css/**" location="/WEB-INF/css/" />
	<resources mapping="/fonts/**" location="/WEB-INF/fonts/" />
	<resources mapping="/js/**" location="/WEB-INF/js/" />
	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" /> 
		<beans:property name="suffix" value=".jsp" /> 
	</beans:bean>	
	<context:component-scan base-package="com.ch.hello" />
</beans:beans>

In servlet-context.xml, the configuration file of Spring, you will see the extension of the view files and the directory of the view files. It is set in InternalResourceViewResolver. You must save on this route otherwise it won't run. 

Base-package has to be reversed 

 

Controller classes are in the src-main-java-com-ch-hello. The classes have annotations. 

In the HomeController.java, you see the @RequestMapping annotation  with /hello, /color, and /gugu, and you can omit the slash. 

HomeController.java

package com.ch.hello;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class HomeController {
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

	@RequestMapping(value = "/hello", method = RequestMethod.GET)
	public String hello(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		String formattedDate = dateFormat.format(date);
		model.addAttribute("serverTime", formattedDate);
		return "home";
	}

	@RequestMapping("/color")
	public String color(Model model) {
		String[] color = { "red", "orange", "yellow", "green", "blue", "navy", "violet" };
		int num = (int) (Math.random() * 7);
		model.addAttribute("color", color[num]);
		return "color";
	}

	@RequestMapping("/gugu")
	public String gugu(Model model) {
		int num = (int) (Math.random() * 8) + 2;
//		int a = num / 0;
		model.addAttribute("num", num);
		return "gugu";
	}
	/*
	 * @ExceptionHandler(ArithmeticException.class) 
	 * public String err() { 
	 * return
	 * "arr-err"; }
	 */
}

@RequestMapping(value = "/hello", method = RequestMethod.GET) -> this format is the original, but you can also write like this: @RequestMapping("/color"). 

In the controller classes, you must use at least one of the following annotations: @Controller, @RequestMapping, @RequestParam, or @ModelAttribute. 

@Controller annotation is the most used annotation.

@RequestMapping annotation is to receive the client's request. 

@Controller
public class HomeController {
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		String formattedDate = dateFormat.format(date);
		model.addAttribute("serverTime", formattedDate);
		return "home";
	}
}

@RequestParam is to receive the name as a value, and its role is the same as request.getParameter("name").

@Controller
public class HomeController {
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(@RequestParam(“name”) String name, Model model) {
}
}

@ModelAttribute is for receiving the value with the DTO class.

@Controller
public class HomeController {
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(@ModelAttribute BoardDTO board, Model model) {
	}
}

 

To demonstrate these concepts, I will show you an example. 

person.jsp

<form action="addr">

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Person</title>
</head>
<body>
	<h2>Name and Address</h2>
	<form action="addr">
		Name : <input type="text" name="name">
		<p>
		Address : <input type="text" name="addr">
		<p>
			<input type="submit" value="Submit">
	</form>
</body>
</html>

The name value will be passed to the Dispatcher Servlet and Controller class.

PersonController.java(Controller Class) receives the name value with the @RequestMapping annotation. It used to be the Handler, but now the annotations take its role. 

PersonController.java

package com.ch.hello;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class PersonController {
	// String name = request.getParameter("name") 
	// @RequestParam("name") String name 
	@RequestMapping("/addr")
	public String addr(@RequestParam("name") String name, 
					   @RequestParam("addr") String addr, 
					   Model model) {
		model.addAttribute("name", name);
		model.addAttribute("addr", addr);
		return "addr";
	}

	@RequestMapping("/addr2")
	public String addr2(@ModelAttribute Person p, Model model) {
		System.out.println("name: "+ p.getName());
		System.out.println("addr: "+ p.getAddr());
		
		model.addAttribute("person", p);
		return "addr2";
	}
}

addr -> @RequestParam

To print out the values, we use EL. 

addr.jsp -> @RequestParam

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
	
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>${name }, your address is ${addr }.
</body>
</html>

Person.java

 <form action="addr2">

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Person</title>
</head>
<body>
	<h2>Name and Address</h2>
		 <form action="addr2">
		Name : <input type="text" name="name">
		<p>
		Address : <input type="text" name="addr">
		<p>
			<input type="submit" value="Submit">
	</form>
</body>
</html>

addr2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
	
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body> Name: ${person.name }<br> 
Address: ${person.addr }
</body>
</html>

addr2 -> @RequestMapping

 

Sometimes, the datatypes of the controller classes are not String type. We will see the example of it. 

SampleController.java

package com.ch.hello;

import java.util.ArrayList;
import java.util.List;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SampleController {
	@RequestMapping("/sample")
	public SampleVo sample() {
		SampleVo sv = new SampleVo();
		sv.setMno(23);
		sv.setFirstName("Meadow");
		sv.setLastName("Cho");
		return sv;
	}

	@RequestMapping("/list")
	public List<SampleVo> list() {
		List<SampleVo> list = new ArrayList<SampleVo>();
		for (int i = 1; i <= 10; i++) {
			SampleVo sv = new SampleVo();
			sv.setMno(i);
			sv.setFirstName("Dodo");
			sv.setLastName("Cox" + i);
			list.add(sv);
		}
		return list;
	}
}

@RestController annotation is a new annotation from Spring version 4.0. The sample method has a DTO class in this controller class, and the list method has a List. 

 

DTO Class datatype

List datatype

 

Spring Framework was first founded by Rod Johnson in his book <Expert One-one-one J2EE Design and Development> and the sample framework in the book was developed to nowadays' Spring Java Framework. It is developed to lessen the complexity of developing applications. 

 

There are a few characteristics of Spring Framework, such as Inversion of Contro, Dependency Injection, Aspect-Oriented Programming, and Model-View-Controller pattern. 

Inversion of Control (IoC) is a design principle that allows classes to be loosely coupled and, therefore, easier to test and maintain. Dependency Injection(DI) is a fundamental aspect of the Spring framework, through which the Spring container “injects” objects into other objects or “dependencies”. Aspect-Oriented Programming(AOP) helps break down the program's logic into several distinct parts called concerns.

 

Configuration

For the configuration on Eclipse, we will download Spring Tool Suit(STS) Program instead of adding a plugin. 

 

Click the link below to download Spring Tools 4 for Eclipse. 

Spring | Tools

 

Spring Tools 4 is the next generation of Spring tooling

Largely rebuilt from scratch, Spring Tools 4 provides world-class support for developing Spring-based enterprise applications, whether you prefer Eclipse, Visual Studio Code, or Theia IDE.

spring.io

If you want to download STS 3.x, click the link below.

Spring Tool Suite 3 · spring-attic/toolsuite-distribution Wiki · GitHub

 

GitHub - spring-attic/toolsuite-distribution: the distribution build for the Spring Tool Suite and the Groovy/Grails Tool Suite

the distribution build for the Spring Tool Suite and the Groovy/Grails Tool Suite - GitHub - spring-attic/toolsuite-distribution: the distribution build for the Spring Tool Suite and the Groovy/Gra...

github.com

I will download this.

Download and pin to taskbar.

This is the first screen that you will see once you run the program. 

It looks similar to Eclipse, but the difference is when you select a wizard. When you select a wizard. In Spring, you can create Spring projects.

Spring
Eclipse

Let's get started with setting encoding. 

In Window-Preferences Search "encoding".

In Workspace, CSS Files, HTML Files, JSP Files, you will set the encoding with your language. In my case, I will set as "UTF-8".

Since it is all set, we will make a spring project.

In File - New - Project, create Spring Legacy Project.

Choose the Spring MVC Project.

Insert the domain reversely. Click Finish, and it is all set!

 

If you can't see the encoding result (In the case of Korean), add this code to the file. 

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

This figure is how MVC in spring works. Since we now use @annotations, we don't pass to the Handler Mapping.

Client -> Dispatcher Servlet -> Controller-> ModelAndView -> ViewResolver -> View

When you run the project in Spring, web.xml will be read first.

 

You will see the prefix and suffix in the servlet-context.xml for the configuration. 

With this, you don't have to write them when you link the page in the HomeController.java.

In the next post, we will look through the main features of Spring Framework: IoC, DI, and AOP.

+ Recent posts