Inversion of Control(IoC)
IoC란 기존 사용자가 모든 작업을 제어하던 것을 특별한 객체에 모든 것을 위임하여 객체의 생성부터 생명주기 등 모든 객체에 대한 제어권이 넘어 간 것을 IoC, 제어의 역전이라고 한다. IOC는 DI와 DL의 의해 구현된다.
DL(Dependency Lookup) 의존성 검색 |
컨테이너에서는 객체들을 관리하기 위해 별도의 저장소에 빈을 저장하는데 개발자들이 컨테이너에서 제공하는 API 를 이용하여 사용하고자 하는 빈을 검색하는 방법이다. |
DI(Dependency Injection) 의존성 주입 |
각 클래스 사이에 필요로 하는 의존관계를 빈 설정 정보를 바탕으로 컨테이너가 자동으로 연결해 주는 것이다. |
스프링 빈(bean) 등록
스프링(Spring) 컨테이너가 관리하는 자바 객체를 빈(Bean)이라 한다.
1. xml 설정파일을 통해 Bean을 직접 등록
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myFirstBean" class="ioc.MyObject" />
<bean id="mySecondBean" class="ioc.MyBean">
<constructor-arg value="임의값"/>
</bean>
<alias name="mySecondBean" alias="hello"/>
</beans>
2. Bean Configuration File에 직접 Bean 등록
@Configuration과 @Bean 어노테이션을 이용하여 Bean을 등록할 수 있다.
어노테이션 | 설명 |
@Configuration | 스프링 IOC Container에게 해당 클래스가 Bean 구성 Class임을 알려주는 어노테이션이다. @Bean을 해당 클래스의 메소드에 적용하면, @Autowired로 빈을 부를 수 있다. (설정에 관련된 정보 어노테이션) |
@Bean | @Bean은 개발자가 직접 제어가 불가능한 외부 라이브러리등을 Bean으로 만들려할 때 사용되는 어노테이션이다. 라이브러리를 Bean으로 등록하기 위해서는 별도로 해당 라이브러리 객체를 반환하는 Method를 만들고 @Bean 어노테이션을 사용하면 된다. |
@Autowired | Bean을 주입받기 위하여 @Autowired 를 사용한다. 속성(field), setter method, constructor(생성자)에서 사용하며 Type에 따라 알아서 Bean을 주입 해준다. Controller 클래스에서 DAO나 Service에 관한 객체들을 주입 시킬 때 많이 사용한다. |
@Configuration
public class MyConfiguration {
@Bean
public MyController sampleController() {
return new SampleController;
}
}
3. 자바 어노테이션 사용하여 Bean 등록
컴포넌트 스캔(Component Scan)을 사용해 @Component 어노테이션이 있는 클래스들을 찾아서 자동으로 빈 등록을 해준다. @Component를 갖는 어노테이션으로 @Controller, @Service, @Repository 등이 존재한다.
어노테이션 | 설명 |
@ComponentScan | @Component, @Service, @Repository, @Controller, @Configuration이 붙은 빈들을 찾아서 Context에 빈을 등록해 주는 어노테이션이다. @ComponentScan 선언에 의해 특정 패키지 안의 클래스들을 자동 스캔하여 @ComponentScan 어노테이션이 있는 클래스들에 대하여 빈 인스턴스를 생성한다. |
@Component | 개발자가 직접 작성한 Class를 Bean으로 등록하기 위한 어노테이션이다. @Component 어노테이션은 Controller, Service, DAO 세가지 이외의 클래스에만 사용한다. @Component → (구체화) → @Controller, @Service, @Repository |
@Controller | Spring MVC의 Controller로 사용되는 클래스 선언을 단순화 시켜주는 어노테이션이다. Controller 클래스의 리턴타입이 String이면 jsp파일명을 의미한다. |
@Service | 비지니스 로직이 들어가는 Service로 사용되는 클래스임을 명시하는 어노테이션이다. |
@Repository | DB연동 작업을 하는 클래스인 DAO에 특화된 어노테이션으로, 해당 클래스에서 발생하는 DB 관련 예외를 spring의 DAOException으로 전환할 수 있는 장점이 있다. |
스프링 MVC 흐름
1. 순서
Client → View → DispatcherServlet → HandlerMapping → Controller → ModelAndView → Controller → DispatcherServlet → ViewResolver → View → Client
(1) DispatcherServlet이 클라이언트에게서 요청을 받는다.
(2) DispatcherServlet이 컨트롤러의 요청 핸들러 메서드를 호출한다.
(3) 컨트롤러는 비지니스 로직 처리를 실행하여 처리 결과를 취득한다.
(4) 처리 결과를 Model로 설정하고 뷰 이름을 반환한다.
(5) DispatcherServlet은 뷰 이름에 대응하는 뷰에 대해서 화면 표시 처리를 의뢰한다.
(6) 클라이언트가 응답을 받고 브라우저에 화면이 표시된다.
2. 역할
DispatcherServlet | 애플리케이션으로 들어오는 모든 Request를 받는 부분. Request를 실제로 처리할 Controller에게 전달하고 그 결과값을 받아서 View에 전달하여 적절한 응답을 생성할 수 있도록 흐름을 제어 |
HandlerMapping | Request URL에 따라 각각 어떤 Controller가 실제로 처리할 것인지 찾아주는 역할 |
Controller | Request를 직접 처리한 후 그 결과를 다시 DispatcherServlet에 돌려주는 역할 |
ModelAndView | Controller가 처리한 결과와 그 결과를 보여줄 View에 관한 정보를 담고 있는 객체 |
ViewResolver | View 관련 정보를 갖고 실제 View를 찾아주는 역할 |
View | Controller가 처리한 결과값을 보여줄 View를 생성 |
JdbcTemplate
1. JdbcTemplate
JdbcTemplate는 DAO객체에서 DB와 연동하기 위해 SQL 연산들을 수행 할 수 있도록 도와주는 JDBC를 위한 틀이다.
*사용방법
(1) DataSource를 설정
(2) JdbcTemplate에서 DataSource를 주입(생성자)
(3) 메소드에 SQL 문 작성
(4) JdbcTemplate 메소드를 활용해 쿼리문 처리
2. JdbcTemplate 메소드
메소드 | 설명 |
query() | sql 파라미터로 전달받은 쿼리를 실행하고 RowMapper를 이용해서 ResultSet의 결과를 자바 객체로 변환해주는 메소드 |
queryForObject() | queryForObject() 메서드는 쿼리 실행 결과가 한 행인 경우 사용할 수 있는 메소드 |
update() | SQL 연산을 통해 데이터베이스를 갱신시켜줄 때(INSERT, DELETE, UPDATE) 사용하는 메소드 |
+) RowMapper<T> 인터페이스
ResultSet에서 데이터를 읽어와 Member 객체로 변환해주는 기능을 제공한다.
RowMapper의 mapRow() 메서드는 SQL 실행 결과로 구한 ResultSet에서 한 행의 데이터를 읽어와 자바 객체로 변환하는 매퍼 기능을 구현한다.
JdbcTemplate 사용
*pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ioc</groupId>
<artifactId>ioc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<spring-version>5.3.25</spring-version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.9.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring-version}</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
*Book.java
package book;
public class Book {
private int no;
private String title;
private int price;
public Book() {}
public Book(int no, String title, int price) {
super();
this.no = no;
this.title = title;
this.price = price;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "Book [no=" + no + ", title=" + title + ", price=" + price + "]";
}
}
*BookRepository.java
package book;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
@Repository
public class BookRepository {
@Autowired
private JdbcTemplate jdbcTemplate;
public List<Book> getAll() {
return jdbcTemplate.query("SELECT no, title, price FROM book", new RowMapper<Book>() {
@Override
public Book mapRow(ResultSet rs, int rowNum) throws SQLException {
int no = rs.getInt("no");
String title = rs.getString("title");
int price = rs.getInt("price");
return new Book(no, title, price);
}
});
}
public Integer count() {
return jdbcTemplate.queryForObject("SELECT COUNT(*) FROM book", Integer.class);
}
public Map<String, Object> minmax() {
return jdbcTemplate.queryForMap("SELECT MIN(price) AS min, MAX(price) as max FROM book");
}
public List<String> titles() {
return jdbcTemplate.queryForList("SELECT title FROM book", String.class);
}
public Book getByNo(int no) {
return jdbcTemplate.queryForObject("SELECT * FROM book WHERE no = ?"
, new BeanPropertyRowMapper<Book>(Book.class)
, no);
}
public int insert(Book book) {
return jdbcTemplate.update("INSERT INTO book (title, price) VALUES (?, ?)"
, book.getTitle(), book.getPrice());
}
public int update(Book book) {
return jdbcTemplate.update("UPDATE book SET title = ?, price = ?, WHERE no = ?",
book.getTitle(), book.getPrice(), book.getNo());
}
}
*DataSourceConfig.java
package config;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
@Configuration
@ComponentScan("book")
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setUrl("jdbc:mysql://localhost:3306/my_db");
ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
ds.setUsername("root");
ds.setPassword("root");
return ds;
}
@Bean
@Autowired
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
return jdbcTemplate;
}
// @Bean
// public BookRepository bookRepository() {
// return new BookRepository();
// }
}
*Test.java
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import book.Book;
import book.BookRepository;
import config.DataSourceConfig;
public class Test {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(DataSourceConfig.class);
BookRepository repo = context.getBean(BookRepository.class);
List<Book> result = repo.getAll();
System.out.println(result);
System.out.println("개수: " + repo.count());
System.out.println("2번 책: " + repo.getByNo(2));
System.out.println("최소, 최대값: " + repo.minmax());
Book newBook = new Book();
newBook.setTitle("jdbc로 row 추가하기");
newBook.setPrice(15000);
int inserted = repo.insert(newBook);
System.out.println("추가된 행 개수: " + inserted);
}
}
[Book [no=2, title=구의 증명, price=6480], Book [no=6, title=테스트용책이름, price=50000], Book [no=7, title=테스트용책이름, price=50000], Book [no=8, title=테스트용책이름, price=50000], Book [no=9, title=테스트용책이름, price=50000], Book [no=10, title=테스트용책이름, price=50000], Book [no=14, title=new title, price=30000], Book [no=15, title=new title, price=30000], Book [no=16, title=new title, price=30000], Book [no=17, title=jdbc로 row 추가하기, price=15000]]
개수: 10
2번 책: Book [no=2, title=구의 증명, price=6480]
최소, 최대값: {min=6480, max=50000}
추가된 행 개수: 1
DB 연동
*pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>spring-mvc</groupId>
<artifactId>spring-mvc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencyManagement>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-framework-bom -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>5.3.25</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.3.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jcl -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jcl</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.9.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<warSourceDirectory>webapp</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>
*WebInit.java
package kr.co.greenart.config;
import javax.servlet.Filter;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
encodingFilter.setEncoding("UTF-8");
encodingFilter.setForceEncoding(true);
return new Filter[] { encodingFilter };
}
}
*WebConfig.java
package kr.co.greenart.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
@ComponentScan("kr.co.greenart")
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/views/", ".jsp");
}
}
*RootConfig.java
package kr.co.greenart.config;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.core.JdbcTemplate;
@Configuration
@PropertySource("classpath:/kr/co/greenart/config/datasource.properties")
public class RootConfig {
@Value("${mysql.dirverClassName}")
private String driverClassName;
@Value("${mysql.url}")
private String url;
@Value("${mysql.userName}")
private String userName;
@Value("${mysql.password}")
private String password;
@Bean
public DataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName(driverClassName);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
@Bean
@Autowired
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
*datasource.properties
mysql.dirverClassName=com.mysql.cj.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/my_db
mysql.userName=root
mysql.password=root
*Book.java
package kr.co.greenart.book;
public class Book {
private int no;
private String title;
private int price;
public Book() {}
public Book(int no, String title, int price) {
super();
this.no = no;
this.title = title;
this.price = price;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "Book [no=" + no + ", title=" + title + ", price=" + price + "]";
}
}
*BookController.java
package kr.co.greenart.book;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class BookController {
private static final Logger logger = LoggerFactory.getLogger(BookController.class);
@Autowired
private BookService service;
@GetMapping("/book")
public String booklist(Model model) {
model.addAttribute("name", service.getAll());
return "booklist";
}
@GetMapping("/book/add")
public String bookadd() {
return "bookform";
}
@PostMapping("/book/add")
public String bookaddpost(@RequestParam(name = "title") String title
, @RequestParam(name = "price") int price) {
Book book = new Book();
book.setTitle(title);
book.setPrice(price);
service.insert(book);
return "redirect:/";
}
}
*BookRepository.java
package kr.co.greenart.book;
import java.util.List;
public interface BookRepository {
public List<Book> getAll();
public int insert(Book book);
}
*BookRepositoryMySQL.java
package kr.co.greenart.book;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository("bookMySQL")
//@Primary
public class BookRepositoryMySQL implements BookRepository {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public List<Book> getAll() {
return jdbcTemplate.query("SELECT * FROM book", new BeanPropertyRowMapper<Book>(Book.class));
}
@Override
public int insert(Book book) {
return jdbcTemplate.update("INSERT INTO book (title, price) VALUES (?, ?)"
, book.getTitle()
, book.getPrice());
}
}
*BookService.java
package kr.co.greenart.book;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class BookService {
@Autowired
@Qualifier("bookMySQL")
private BookRepository repo;
public List<Book> getAll() {
return repo.getAll();
}
public int insert(Book book) {
return repo.insert(book);
}
}
*HandlerTestController.java
package kr.co.greenart.handler;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class HandlerTestController {
@GetMapping("/void") // mapping 경로와 같은 view 이름으로 forward
public void voidView() {
}
@GetMapping("/forward")
public String forward() {
return "index";
}
@GetMapping("/mv")
public ModelAndView mv() { // 응답코드, Model의 Attribute, forward View 이름 설정 가능한 객체
ModelAndView mv = new ModelAndView();
mv.addObject("asdf", "asdf");
mv.setStatus(HttpStatus.OK);
mv.setViewName("index");
return mv;
}
@GetMapping("/entity")
public ResponseEntity<String> entity() {
String body = "body 내용";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
ResponseEntity<String> response = new ResponseEntity<String>(body, HttpStatus.OK);
return response;
}
@GetMapping("/entity2")
public ResponseEntity<String> entity2() {
return ResponseEntity.ok().header("Content-Type", "plain/text").body("응답 body 내용");
}
}
*IndexController.java
package kr.co.greenart.index;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class IndexController {
private static final Logger logger = LoggerFactory.getLogger(IndexController.class);
@RequestMapping(value = { "/", "/index.jsp" }, method = RequestMethod.GET)
public String index() {
logger.info("사용자가 INDEX 페이지를 요청하였습니다.");
return "index";
}
}
*TestConnection.java
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import kr.co.greenart.config.RootConfig;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { RootConfig.class })
public class TestConnection {
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void testConnection() {
int result = jdbcTemplate.queryForObject("SELECT 1", Integer.class);
assertEquals(1, result);
}
}
*index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Index</title>
</head>
<body>
<h1>INDEX PAGE</h1>
<a href="./book">책 목록 보기</a>
<a href="./book/add">책 추가하기</a>
</body>
</html>
*bookform.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>책 추가 페이지</title>
</head>
<body>
<form action="" method="post">
<input type="text" name="title">
<input type="number" name="price">
<input type="submit">
</form>
</body>
</html>
*booklist.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>책 목록</title>
</head>
<body>
<h1>책 목록을 보여줄 view</h1>
<p>${ name }</p>
</body>
</html>
*void.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>
<h1>Void View</h1>
</body>
</html>