JAVA/JAVA개발자 양성과정

[Spring] Spring MVC 아키텍처/작동 원리 이해하기

👩‍💻 자바 개발자 양성과정 54일차

  1. JAVA에서 csv파일 읽어와서 DB에 추가하기
  2. Spring MVC
  3. pring 아키텍처 이해하기 - resources 폴더 사용하기
  4. Spring 아키텍처 이해하기 -  프로젝트 인덱스 수정 (접속 페이지)
  5. Spring 작동 원리 이해 - 주소 보고 이해하기
  6. Spring Legacy에서 component-scan 하는 위치

 


🌜 JAVA에서 csv파일 읽어와서 DB에 추가하기

아키텍쳐

dbinfo.properties

db.driverClass=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/test
db.username=root
db.password=1234

 

mybatis-config.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 type="com.example.vo.StudentVO" alias="studentVo" />
	</typeAliases>
</configuration>

 

mybatis-mapper.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="Student">
	
	<!-- 이 결과값을 JdbcDriver에게 넘긴다. -->	
	<!-- parameterType: Java에서 넘어오는 값의 Type -->
	<insert id="insert" parameterType="studentVo" statementType="PREPARED">
		INSERT INTO student
		VALUES(#{hakbun}, #{name}, #{kor} ,#{eng}, #{mat}, #{edp}, #{tot}, #{avg}, #{grade})
	</insert>
	
	<resultMap type="studentVo" id="studentResultMap">
		<result property="hakbun" javaType="String" column="hakbun" jdbcType="CHAR"/>
		<result property="name" javaType="String" column="name" jdbcType="VARCHAR"/>
		<result property="kor" javaType="int" column="kor" jdbcType="TINYINT"/>
		<result property="eng" javaType="int" column="eng" jdbcType="TINYINT"/>
		<result property="mat" javaType="int" column="mat" jdbcType="TINYINT"/>
		<result property="edp" javaType="int" column="edp" jdbcType="TINYINT"/>
		<result property="tot" javaType="int" column="tot" jdbcType="SMALLINT"/>
		<result property="avg" javaType="double" column="avg" jdbcType="DECIMAL"/>
		<result property="grade" javaType="java.lang.Character" column="grade" jdbcType="CHAR"/>
	</resultMap>
	
	
	<select id="selectList" resultMap="studentResultMap" resultType="studentVo" statementType="PREPARED">
		SELECT * FROM Student
		ORDER BY tot DESC
	</select>
	
</mapper>

 

 

bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="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-4.3.xsd">

	<context:component-scan 	base-package="com.example" />
	<context:property-placeholder	location="classpath:dbinfo.properties" />
	
	<!-- HikariCP 설정 Start-->
	<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
		<property name="driverClassName" value="${db.driverClass}" />
		<property name="jdbcUrl" value="${db.url}" />
		<property name="username" value="${db.username}" />
		<property name="password" value="${db.password}" />				
	</bean>

	<bean id="dataSource"
		class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
		<constructor-arg name="configuration" ref="hikariConfig" />
	</bean>
	<!-- HikariCP 설정 End -->
	
	<!-- mybatis-spring 설정 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="configLocation"	value="classpath:mybatis-config.xml" />
		<property name="mapperLocations">
			<list>
				<value>classpath:mybatis-mapper.xml</value>
			</list>
		</property>
	</bean>
	
	<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg ref="sqlSessionFactory" />
	</bean>

</beans>

 

StudentDaoImpl.java

package com.example.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.example.vo.StudentVO;

import lombok.extern.java.Log;

@Log
@Repository("studentDao")
public class StudentDaoImpl implements StudentDao {

	@Autowired
	private SqlSession sqlSession;
	
	
	@Override
	public void insertStudent(StudentVO student) {
		this.sqlSession.insert("Student.insert", student);
		log.info(student.getName() + "Insert Success."); 
	}

	@Override
	public StudentVO selectStudent(String hakbun) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<StudentVO> selectAllStudent() {
		return this.sqlSession.selectList("Student.selectList");
	}

	@Override
	public void updateStudent(StudentVO student) {
		// TODO Auto-generated method stub

	}

	@Override
	public void deleteStudent(String hakbun) {
		// TODO Auto-generated method stub

	}

}

 

StudentServiceImpl.java

package com.example.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.dao.StudentDao;
import com.example.vo.StudentVO;

@Service("studentService")
public class StudentServiceImpl implements StudentService {
	
	@Autowired
	private StudentDao studentDao;
	
	@Override
	public void create(StudentVO student) {
		this.studentDao.insertStudent(student);
	}

	@Override
	public StudentVO read(String hakbun) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<StudentVO> readAll() {
		return this.studentDao.selectAllStudent();
	}

	@Override
	public void update(StudentVO student) {
		// TODO Auto-generated method stub

	}

	@Override
	public void delete(String hakbun) {
		// TODO Auto-generated method stub

	}

}

 

Input.java

 package com.example.test;

import java.util.List;

import com.example.vo.StudentVO;

public class Calc {
	private List<StudentVO> list;

	public Calc(List<StudentVO> list) {
		this.list = list;
		this.list.forEach(student -> this.calc(student));
	}
	
	private void calc(StudentVO student) {
		int tot = student.getKor() + student.getEng() + student.getMat() + student.getEdp();
		double avg = tot /4.;
		char grade = (avg >= 90)? 'A':
								(avg >= 80)?'B':
									(avg >= 70)?'C':
										(avg >= 60)?'D': 'F';
		student.setTot(tot);
		student.setAvg(avg);
		student.setGrade(grade);
	}
	
}

 

Calc.java

package com.example.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.util.Scanner;

import com.example.vo.StudentVO;

import lombok.extern.java.Log;

@Log
public class Input {
	private List<StudentVO> list;
	private Scanner scan;
	
	
	public Input(List<StudentVO> list) throws IOException {
		this.list = list;
		String path = "C:/Temp/sungjuk_utf8.csv";
		this.scan = new Scanner((Readable) new BufferedReader(new FileReader(path)));
	}
	
	public void input() {
		log.info("tttttt");
		while(this.scan.hasNext()) {
			
			String line = this.scan.nextLine();
			String[] array = line.split(","); 
			StudentVO student = new StudentVO(array[0].trim(),
					array[1].trim(), Integer.parseInt(array[2].trim()),
					Integer.parseInt(array[3].trim()), 
					Integer.parseInt(array[4].trim()),
					Integer.parseInt(array[5].trim()));
			this.list.add(student);
			log.info(student.toString());
		}
	}
}

 

StudentBeanJUnitSpringTest.java

package com.example.test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import com.example.service.StudentService;
import com.example.vo.StudentVO;

import lombok.extern.java.Log;


@Log
@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations = { "classpath:beans.xml" })
@Component
class StudentBeanJUnitSpringTest2 {

	@Autowired
	private StudentService studentService;
	private List<StudentVO> list;

	@Disabled
	@BeforeEach
	public void init() { 
		try {
			list = new ArrayList<StudentVO>();
			Input input = new Input(list);
			input.input();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Test
	@DisplayName("Student Insert")
	void test() {
		Calc calc = new Calc(this.list);
		this.list.forEach(student -> this.studentService.create(student));
	}	
	
	@Disabled
	@Test
	@DisplayName("SelectListStudent Test")
	void test1() {
		this.studentService.readAll().forEach(student -> System.out.println(student));;
	}
}

 


🌜 Spring MVC

 

이걸 서버에서 돌리면

가장먼저 프로젝트 내 web.xml이 실행된다.

 

Spring MVC Demo 처리 순서
◼ Web Browser의 요청을 web.xml의 <url-pattern></url-pattern>를 통해 /의
요청을 받는다.
◼ servlet-name이 appServlet인 servlet-class는
org.springframework.web.servlet.DispatcherServlet이다.
◼ 이 DispatcherServlet는 Loading하면서 /WEB-INF/spring/appServlet/servletcontext.xml를 Parameter로 초기화한다.
◼ servlet-context.xml에서 <context:component-scan base-package="com.exampl
e.biz" />를 통해 Scan을 base-package에서 한다.
◼ com.example.biz에 @Controller를 찾는다.
◼ @Controller가 있는 HomeController.java에서 @RequestMapping(value = "/", m
ethod = RequestMethod.GET)가 설정되어 있는 method인 public String home(L
ocale locale, Model model)를 찾는다.
◼ 왜냐하면 지금 Browser가 요청한 Method는 GET이고, 요청 경로는 /이기 때문이
다.

 

 


🌜 Spring 아키텍처 이해하기 - resources 폴더 사용하기

 

 

resources폴더를 만들어서 이미지를 넣고 호출해보자

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<html>
<head>
	<title>Home</title>
</head>
<body>
<h1>
	Hello world!  
</h1>

<p>  The time on the server is ${serverTime}. </p>
<img src="resources/idol.png">
</body>
</html>

 

잘 출력된다.

 

 

 

이미지를 다른 폴더에 넣고 호출해보자

images폴더를 만들어서 이미지를 넣고 호출해보자

 

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<html>
<head>
	<title>Home</title>
</head>
<body>
<h1>
	Hello world!  
</h1>

<p>  The time on the server is ${serverTime}. </p>
<img src="images/idol.png">
</body>
</html>

안나온다.

 

 

/src/main/webapp/WEB-INF/spring/appServlet/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 https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://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/" />

	<!-- 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.example.biz" />
	
	
	
</beans:beans>

<resources mapping="/resources/**" location="/resources/" />

<resources mapping="논리경로" location="물리경로" />

 

이곳에 경로를 추가를 해야지만 다른 resources외에 폴더를 사용할 수 있다.

<resources mapping="/images/**" location="/images/" />

 

 

<?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 https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://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="/images/**" location="/images/" />

	<!-- 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.example.biz" />
	
	
	
</beans:beans>

이렇게 수정하고 나니 images의 이미지도 잘 출력된다.

 

 


🌜 Spring 아키텍처 이해하기 -  프로젝트 인덱스 수정 (접속 페이지)

Servrs에서 톰캣서버 더블클릭
수정하려는 프로젝트 선택후 Edit클릭
인덱스 페이지로 설정할 페이지를 작성하고 OK클릭

 

여기 부분을 수정하고 프로젝트 run하면 인덱스 페이지가 수정된다.

 


🌜 Spring 작동 원리 이해 - 주소 보고 이해하기

localhost:8080까지는 웹서버와 톰캣서버가 읽는다.

/biz는 웹xml가 읽는다.

 

/view는 Controller가 읽는다.

 


🌜 Spring Legacy에서 component-scan 하는 위치

 

728x90
반응형