@RequestMapping을 클래스 수준에 줄 수 있다.

 

같은 이름 맵핑 되었을때 가는 곳?

package kh.spring.board;

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

@Controller
public class MemberController {

	@RequestMapping("test")
	public String test() {
		return "member/test";
	}
	
}
package kh.spring.board;

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

@Controller
public class BoardController {
	@RequestMapping("test")
	public String test() {
		return "board/test";
	}
	
}

 

 

컴퍼넌트 스캔을 진행해서 빈으로 만들어 수집

클라이언트 요청을 받을 수있는 곳 검사

같은 이름일 경우 에러 발생 (Ambiguous 모호한)

 

1. 같은 이름 만들지 않기

2. 또는

리쿼스트맵핑을 컨트롤러( 클래스 수준)에도 걸수 있다.

package kh.spring.board;

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

@Controller

@RequestMapping("/member/")
public class MemberController {

	@RequestMapping("test")
	public String test() {
		return "member/test";
	}
	
}


package kh.spring.board;

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

@Controller

@RequestMapping("/member/")
public class MemberController {

	@RequestMapping("test")
	public String test() {
		return "member/test";
	}
	
	@RequestMapping("signup")
	public String signup() {
		return "signup";
	}
	@RequestMapping("login")
	public String login() {
		return "member/test";
	}
	
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="C"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
</head>
<body>
	로그인 / 회원가입
	<c:choose>
		<c:when test="${!empty loginInfo}">
                     
   	${loginInfo}님 환영합니다!
	<button id="Logout">로그아웃</button>
			<script>
				$("#Logout").on("click", function() {
					location.href = "LogoutController";
				})
			</script>

		</c:when>
		<c:otherwise>
			<div class="wrapper">
				<form action=LoginController method="post">
					<table align=center border="1px" style="text-align: center">
						<tr>
							<td><b>Login</b></td>
						</tr>
						<tr>
							<td><input type="text" name="id" placeholder="Input your ID"></td>
						</tr>
						<tr>
							<td><input type="password" name="pw"
								placeholder="Input your PW"></td>
						</tr>
						<tr>
							<td><input type="submit" id="login" value="Login"> <input
								type="button" id="signup" value="Sign up"><br> <input
								type="checkbox">Remember my ID</td>
						</tr>
					</table>
				</form>
			</div>
			<script>
				$("#signup").on("click", function() {
					location.href = "signup"
				})
				$("#login").on("click", function() {
					location.href = "login"
				})
			</script>

		</c:otherwise>
	</c:choose>


</body>
</html>

 

3시간 놓친 진도

 

[김지수] [오전 11:54] delete 하고 있어요 지금
[김지수] [오전 11:54] output 페이지도 만들었구요~
[김지수] [오전 11:54] dao에 기능 추가하시면 될 것 같아요

 

[김지수] [오전 11:55] 그 컨트롤러에
[김지수] [오전 11:55] 메서드 매개 변수 부분에
[김지수] [오전 11:56] 동적 타입 바인딩 하는 거
[김지수] [오전 11:56] 조금 추가해서 ㅁ배웠는데
[김지수] [오전 11:56] Model이랑 ModelAndView
[김지수] [오전 11:56] 이 두개밖에 안 했어요
[김지수] [오전 11:56] 설명 간단해서 검색하시면서 보시면 될 것 같아용

https://hongku.tistory.com/116

 

SpringMVC :: 컨트롤러(Controller), Model, ModelAndView 사용법

스프링 MVC 컨트롤러 (Controller) 기본적인 흐름은 client가 요청을 하면, @Controller에 진입한다. 컨트롤러는 요청에 대한 작업을 수행하고, 뷰쪽으로 데이터를 전달한다. 컨트롤러 클래스 제작 순서 @C

hongku.tistory.com

 


 

forward , redirect 차이

 

동적 타입 바인딩

(디폴트생성자 필요!)


넘어온 값을 데이터베이스에 저장

 

 

 

MessagesDAO 클래스 만들기


동시접속자가 다량으로 접속했을 때를 대비한 DBCP 적용

DataBase Connection Pool

커넥션들을 가둬놓은 울타리

순간 접속자가 대량으로 발생할 때, 미리 생성해 놓은 Connection 객체를 대여하는 방식으로 접속자를 제한하는 기술

1. 커넥션 객체를 미리 몇십개 정도 pool에 저장

2. 사용자가 오면 커넥션을 빌려줌

3. 커넥션 개수 이상의 사용자는 대기 시킴

4. 먼저 사용한 사용자가 반환하면 순서대로 배분

5. 사용자는 대기해야 하지만 서버가 터지니는 않음

 


 

ojdbc6 추가 필요

 

porm.xml

 

메이븐 사이트의 링크가 끊겨있는 경우 있음

https://mvnrepository.com/artifact/com.oracle/ojdbc6/12.2.0.1

 

Maven Repository: com.oracle » ojdbc6 » 12.2.0.1

com.oracle ojdbc6 12.2.0.1 // https://mvnrepository.com/artifact/com.oracle/ojdbc6 compile group: 'com.oracle', name: 'ojdbc6', version: '12.2.0.1' // https://mvnrepository.com/artifact/com.oracle/ojdbc6 libraryDependencies += "com.oracle" % "ojdbc6" % "12

mvnrepository.com

 

 

다운로드 받는 사이트 목록을 추가

	<repositories>
		<repository>
			<id>OJDBC6 Repo</id>
			<url>http://maven.icm.edu.pl/artifactory/repo/</url>
		</repository>
	</repositories>

 

그래도 오류!

저장소 문제

 

직접 쓰기

	<repositories>
		<repository>
			<id>OJDBC6 Repo</id>
			<url>http://www.datanucleus.org/downloads/maven2/</url>
		</repository>
	</repositories>
		<!-- DB Related -->
		<dependency>
			<groupId>oracle</groupId>
			<artifactId>ojdbc6</artifactId>
			<version>11.2.0.3</version>
		</dependency>


https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2/2.7.0

 

Maven Repository: org.apache.commons » commons-dbcp2 » 2.7.0

 

mvnrepository.com

DBCP

		<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-dbcp2</artifactId>
			<version>2.7.0</version>
		</dependency>

 

 

 

DAO를 new 할 때마다 베이직 데이터 소스도 new 되어서 너무 많아짐 -> 싱글턴 패턴 적용

 

스프링에서 new를 하긴 해야 하는데...? : 스프링에게 만들자

 

root-context.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<!-- Root Context: defines shared resources visible to all other web components -->
		
		<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
			<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
			<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
			<property name="username" value="kh"/>
			<property name="password" value="kh"/>
			<property name="initialSize" value="30"/>
		</bean>
</beans>

싱글턴으로 적용

setter 말고 property로 넣기

 

 

DBCP 쓸 준비 끝

 


DAO

package kh.spring.dao;

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

import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;

public class MessagesDAO {
	
	
	@Autowired
	private BasicDataSource bds;

	private Connection getConnection() throws Exception {
		return bds.getConnection();
	}
}

 

Bean으로 만들어져 있는것 연결

@Autowired

디팬던시 인젝션

스프링이 가진 것들 중 BasicDataSource 자료형을 찾아서 연결

같은자료형이라 자동연결이 안될경우 아이디를 주고 퀄리파이어를 준다.

 

 

 

new는 유지보수에 불리

DAO 생성시마다 커넥션풀 까지 같이 생성되면 서버 터짐

 

 

 

DBCP를 쓰기 위한 인스턴스 : 커넥션

 

 

HomeController

package kh.spring.controller;

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

import kh.spring.dao.MessagesDAO;
import kh.spring.dto.MessagesDTO;

@Controller
public class HomeController {

	private MessagesDAO mdao;

	@RequestMapping("/")
	public String home() {
		return "home";
	}

	@RequestMapping("input")
	public String toInput() {
		return "messages/input";
		// WEB-INF/views/messages/input.jsp
	}

	@RequestMapping("inputProc")
	public String inputProc(MessagesDTO dto) {

		System.out.println(dto.getWriter()+" : "+dto.getMessage());
		return "redirect:/";
	}
}

 

MessagesDAO 아직 존재하지 않음

 

@Component로 스캔시 MessagesDAO 생성되도록 설정

 

DAO 역할을 하는 경우 @Component 보다는 @Repository 를 붙인다

 

@Repository 

@Component를 상속받아서 기능은 같다

당장은 큰 차이가 없지만 미래에 Repository에 업데이트가 발생할 경우를 대비해서

 

MessagesDAO

package kh.spring.dao;

import java.sql.Connection;

import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class MessagesDAO {
	
	
	@Autowired
	private BasicDataSource bds;

	private Connection getConnection() throws Exception {
		return bds.getConnection();
	}
}

 

HomeController

package kh.spring.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import kh.spring.dao.MessagesDAO;
import kh.spring.dto.MessagesDTO;

@Controller
public class HomeController {

	@Autowired
	private MessagesDAO mdao;

	@RequestMapping("/")
	public String home() {
		return "home";
	}

	@RequestMapping("input")
	public String toInput() {
		return "messages/input";
		// WEB-INF/views/messages/input.jsp
	}

	@RequestMapping("inputProc")
	public String inputProc(MessagesDTO dto) {

		System.out.println(dto.getWriter()+" : "+dto.getMessage());
		return "redirect:/";
	}
}

 

단 컴포넌트스캔(component-scan)의 스캔 범위가 controller 패키지로 한정되어 있음

 

 

servlet-context.xml 에서 범위를 바꿔야한다

	<context:component-scan base-package="kh.spring" />

 

 

<?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="kh.spring" />
	
	
	
</beans:beans>

 

오타 locahost

더보기
java.sql.SQLException: Cannot create PoolableConnectionFactory (IO 오류: The Network Adapter could not establish the connection)
	at org.apache.commons.dbcp2.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:669)
	at org.apache.commons.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:544)
	at org.apache.commons.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:753)
	at kh.spring.dao.MessagesDAO.getConnection(MessagesDAO.java:20)
	at kh.spring.dao.MessagesDAO.insert(MessagesDAO.java:25)
	at kh.spring.controller.HomeController.inputProc(HomeController.java:30)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:543)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:615)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:818)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1627)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.sql.SQLRecoverableException: IO 오류: The Network Adapter could not establish the connection
	at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:458)
	at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:546)
	at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:236)
	at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
	at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:521)
	at org.apache.commons.dbcp2.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:55)
	at org.apache.commons.dbcp2.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:355)
	at org.apache.commons.dbcp2.BasicDataSource.validateConnectionFactory(BasicDataSource.java:115)
	at org.apache.commons.dbcp2.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:665)
	... 44 more
Caused by: oracle.net.ns.NetException: The Network Adapter could not establish the connection
	at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:392)
	at oracle.net.resolver.AddrResolution.resolveAndExecute(AddrResolution.java:434)
	at oracle.net.ns.NSProtocol.establishConnection(NSProtocol.java:687)
	at oracle.net.ns.NSProtocol.connect(NSProtocol.java:247)
	at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1102)
	at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:320)
	... 52 more
Caused by: java.net.UnknownHostException: locahost
	at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
	at java.net.InetAddress$2.lookupAllHostAddr(Unknown Source)
	at java.net.InetAddress.getAddressesFromNameService(Unknown Source)
	at java.net.InetAddress.getAllByName0(Unknown Source)
	at java.net.InetAddress.getAllByName(Unknown Source)
	at java.net.InetAddress.getAllByName(Unknown Source)
	at oracle.net.nt.TcpNTAdapter.connect(TcpNTAdapter.java:117)
	at oracle.net.nt.ConnOption.connect(ConnOption.java:133)
	at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:370)
	... 57 more

package kh.spring.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;

import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import kh.spring.dto.MessagesDTO;

@Repository
public class MessagesDAO {
	
	
	@Autowired
	private BasicDataSource bds;

	private Connection getConnection() throws Exception {
		return bds.getConnection();
	}
	
	public int insert(MessagesDTO dto) throws Exception {
		String sql = "insert into messages values(messages_seq.nextval,?,?,sysdate)";
		try(Connection con = this.getConnection();
			PreparedStatement pstat = con.prepareStatement(sql);){
			pstat.setString(1, dto.getWriter());
			pstat.setString(2, dto.getMessage());
			int result = pstat.executeUpdate();
			con.commit();
			return result;
			
		}
	}
}
package kh.spring.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import kh.spring.dao.MessagesDAO;
import kh.spring.dto.MessagesDTO;

@Controller
public class HomeController {

	@Autowired
	private MessagesDAO mdao;

	@RequestMapping("/")
	public String home() {
		return "home";
	}

	@RequestMapping("input")
	public String toInput() {
		return "messages/input";
		// WEB-INF/views/messages/input.jsp
	}

	@RequestMapping("inputProc")
	public String inputProc(MessagesDTO dto) {
		try {
			int result = mdao.insert(dto);
		}catch(Exception e) {
			e.printStackTrace();
			return "error";
		}
		return "redirect:/";
	}
}

 


HomeController.java

package kh.spring.controller;

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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class HomeController {
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		return "home";
	}
}

매서드 구분을 하지 않는다면 (인자값이 하나라면)

	@RequestMapping("/")

 

 

package kh.spring.controller;

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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class HomeController {
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home() {
		return "home";
	}
}

 


제이쿼리 템플릿에 추가

home.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>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
</head>
<body>

</body>
</html>

 

<%@ 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>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
</head>
<body>
	<a href="input">toInput</a>
	<a href="output">toOutput</a>
</body>
</html>

 


서버 가동

 

server.xml의 포트번호와 path명 입력

http://localhost:8085/controller/

 


toInput

package kh.spring.controller;

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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class HomeController {
	@RequestMapping("/")
	public String home() {
		return "home";
	}
	
	@RequestMapping("input")
	public String toInput() {
		return "input";
	}
}

 

input.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>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
</head>
<body>
  여기가 Input
</body>
</html>

잘 포워드 된 것 확인


주소 단순화 하기

 

path 비우기

 

포트번호 80으로

톰캣 설정파일을 변경했을 때는 서버 재시동 해야 함

 

 


폴더 생성

 

messages 폴더에 input.jsp 넣기

 

컨트롤러 경로 변경

package kh.spring.controller;

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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class HomeController {
	@RequestMapping("/")
	public String home() {
		return "home";
	}
	
	@RequestMapping("input")
	public String toInput() {
		return "messages/input";
		// WEB-INF/views/messages/input.jsp
	}
}

 

forward/redirect

포워드는 서버가 보여주는 값만 변환, 클라이언트측 에서는 요청한 url로 유지

forward - 클라이언트에게 가라는 것이 아니라 서버가 내부적으로 페이지를 전환하는 것. 그래서 client가 보는 페이지 주소는 유지됨

 

리다이렉트는 클라이언트 url을 바꾸는 명령 : 클라이언트의 주소창이 바뀐다. request 초기화

포워드는 서버쪽 리스펀스에다 해당 페이지를 담아서 보내주는 것 : 클라이언트의 주소창 유지. request 유지

 

redirect:home 으로 보내면 home에 맵핑되는 페이지 없으므로 에러


input.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>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
</head>
<body>
 
 	<form action="inputProc" method="post">
 		<input type=text name="writer">
 		<input type=text name="message">
 		<button>전송</button>
 	</form>
 
</body>
</html>

버튼의 기본타입은 submit

 

 

package kh.spring.controller;

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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class HomeController {
	@RequestMapping("/")
	public String home() {
		return "home";
	}
	
	@RequestMapping("input")
	public String toInput() {
		return "messages/input";
		// WEB-INF/views/messages/input.jsp
	}
	
	@RequestMapping("inputProc")
	public String inputProc() {
		return "home";
	}
}

입력이 끝나면 다시 홈으로


값을 받는법?

	@RequestMapping("inputProc")
	public String inputProc() {
		return "home";
	}

request라는 객체 없음

 

스프링에서는 필요하면 매개변수 만들고 필요없으면 매개변수 안만들면된다.

	@RequestMapping("inputProc")
	public String inputProc(HttpServletRequest request) {
		String writer = request.getParameter("writer");
		String message = request.getParameter("message");
		System.out.println(writer+" : "+message);
		
		return "home";
	}

 

한글은 깨짐


포워드로 돌아왔으므로 request 유지됨

그 상태에서 F5를 하면 계속 제출

 

리다이렉트로 리퀘스트 초기화 해야함!

	@RequestMapping("inputProc")
	public String inputProc(HttpServletRequest request) {

		String writer = request.getParameter("writer");
		String message = request.getParameter("message");
		System.out.println(writer+" : "+message);
		
		return "redirect:/";
	}

매개변수

 

	@RequestMapping("inputProc")
	public String inputProc(HttpServletRequest request) {

		String writer = request.getParameter("writer");
		String message = request.getParameter("message");
		System.out.println(writer+" : "+message);
		
		return "redirect:/";
	}

 

	@RequestMapping("inputProc")
	public String inputProc(String writer, String message) {

		System.out.println(writer+" : "+message);
		return "redirect:/";
	}

보내는 값의 name값과 매개변수 이름과 동일해야 자동으로 대입 된다.

 

 

	@RequestMapping("inputProc")
	public String inputProc(HttpServletRequest requset,String writer, String message) {

		System.out.println(writer+" : "+message);
		return "redirect:/";
	}

원하는 만큼 매개변수를 만들 수 있다.

 


MessagesDTO 생성

package kh.spring.dto;

public class MessagesDTO {

	private int seq;
	private String writer;
	private String message;
	
	
	public MessagesDTO() {}
	public MessagesDTO(int seq, String writer, String message) {
		super();
		this.seq = seq;
		this.writer = writer;
		this.message = message;
	}
	public int getSeq() {
		return seq;
	}
	public void setSeq(int seq) {
		this.seq = seq;
	}
	public String getWriter() {
		return writer;
	}
	public void setWriter(String writer) {
		this.writer = writer;
	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
	
	
}

 

HomeController

	@RequestMapping("inputProc")
	public String inputProc(MessagesDTO dto) {

		System.out.println(dto.getWriter()+" : "+dto.getMessage());
		return "redirect:/";
	}

 

 

매개변수로 바로 dto로 넣어 줄 수 있음

- request.getParameter("") 코드 필요 없음!

 

멤버필드 이름과 클라이언트에서 보내주는 네임이 같다면

Dynamic Type Binding

다이나믹 타입 바인딩 

 

MessagesDTO에서 값이 주어지지 않은 seq에는 뭐가 들어갈까?

- null도 객체이므로 아님

- 쓰레기값은 스텍메모리를 사용할때 들어감

- 아무값도 아니라면 0 값이 들어간다.

 

(MessagesDTO 디폴트생성자 필요!)


 

스프링 컨테이너의 구동

 

1. web.xml  : Tomcat-Servlet Container 구동 

 

추가 xml로 읽어라

 

2. 스프링컨테이너 생성

Spring Container를 생성

root-context.xml을 읽는다 (설정파일)

servlet-context.xml을 읽는다 (어플리케이션 요청 처리 설정파일)

root-context.xml과 servlet-context.xml이 절대적인 건 아님 (다른 파일 생성해서 경로명 변경해도 가능)

하지만 스프링이 권장하는 방식

 

 

스프링 컨테이너는 자기 영역을 가지고 있음

빈태그를 자기 영역에 인스턴스로 만들어서 로딩

제어의 역전 , 빈을 미리 만들어놓고 언제 사라질지 싱글턴일지 자기가 결정

쓰고 싶을때 오토와이어드 어노테이션으로 찾아씀

 

 

검색은 디팬던시룩업 (웹환경에서는 쓰기 번거로움)


네이티브 프로젝트

 

스프링 컨테이너 생성 (영역과 빈 인스턴스 미리 생성)

TV 타입인 애를 검색 // DL

인스턴스 담고 사용

 

웹 프로젝트에서는 web.xml에서 스프링컨테이너 생성

점을 찍을 변수가 없음 (getBean 할 변수가 없다)

-> 방법이 불가능 하진 않지만 불편

 

오토와이어드로 디팬던시 인젝션 사용

 

Q. 

 

 

스프링 풀에 인스턴스 만들기

- 컴퍼넌트 Annotation 을 붙이고 컴포넌트 스캔을 돌리면 인스턴스를 만드는 작업

- XML에 빈태그로 써서 인스턴르를 반드는 작업

 

XML : 기능

Annotation : 편의성


루트 컨텍스트는 비어져 있다

 

서블릿-컨텍스트

 

리턴 = 포워드

뷰리졸버가 앞뒤로 prefix suffix

 

빈태그는 스프링컨테이너의 풀 에다가 인스턴스를 미리 만들어 놓자는 의미

 

우리가 만들어서 사용하는 인스턴스도 있고

뷰리졸버 처럼 만들어만 놓으면 스프링이 알아서 사용하는 인스턴스도 있다.

 

component-scan

해당 패키지에서 컴포넌트를 찾는다

 

컴포넌트와

컴포넌트어노테이션을 상속받은

컨트롤러, 서비스, 리파지토리 어노테이션도 스캔되어 스프링풀에 인스턴스가 된다.

 

컨트롤러 역할의 경우, 꼬리표 달아놓음

 

 

 

클라이언트가 요청시

요청을 처리할 대상을 찾아야함

컨트롤러 외에 다른 인스턴스 뒤지는 것은 낭비

바로 찾을 수 있게 컨트롤러에는 꼬리표

홈컨트롤러가 요청 처리후 "home" 리턴

 

뷰페이지 이름을 처리 해 줄 수 있는 인스턴스는?

VR 뷰리졸버가 "home" 앞뒤에 프리픽스 처리 -> JSP로 가는 경로 완성

 

 

프레임워크와 WAS

- 컨테이너 : 자신들만의 체계가 있음

 

Maven

  • 라이브러리(Library) 자동화
  • 배포(Deploy) 자동화

Spring

  • IOC (클래스 빈 인스턴스를 만들어준다) : DL / DI 의 배경이 된다
  • AOP : 관점지향프로그래밍 (하나의 코드를 일관적으로 여러코드에 적용)
  • 유지보수 : 실력 평준화

Tomcat

  • Web protocol
  • WAS

Mybatis

  • DB 이식성
  • 동적쿼리 생성 편하다

EL / JSTL


3.9.12. 설치

 


pome.xml / Maven Dependencies : 메이븐 관련

src : 프론트엔드 관련, JSP CSS IMG

src/main/java : 백엔드 서블릿, 자바코드

src/main/resources : 백엔드 리소스

target : 만든 자바 코드들과 배포에 필요한 것들이 모인다.



web.xml 문서

 

자동화가 가능한 부분은 Spring이 해준다.

 

초기 기본 모델

 

 

리쿼스트를 디스패처서블릿에 보낸다.

 

요청을 처리해줄 대상을 검색해야 함 -> 핸들러맵퍼 라는 인스턴스에 요청

 

원래는 핸들러맵퍼 코드를 다 만들어 줘야함 

 

컨트롤러 타고 디스패처에게 돌아옴 : view페이지 정보 (어디로 가야하는지)

 

뷰 리졸버가 처리해서 JSP로 보내줌

 


초기 확장형

동적쿼리가 필요하다면 mybatis 추가

서비스레이어 추가


 

변경 개선 버전

 

프론트컨트롤러를 만들고 리쿼스트 맵핑을 함

  • 핸들러맵퍼 + 컨트롤러의 기능
  •  


 

 

 

인스턴스를 생성하되, 값을 할당하라는 설정(setter)

 


포워딩이 될 수 없음
뷰리졸버를 거치지 않고 스트링으로 전달하는 방법 (@ResponseBody)

 

'디지털 컨버전스 > Java Script' 카테고리의 다른 글

[JS] 파일 업로드 추가하기  (0) 2020.06.22
[] XSS  (0) 2020.06.03
[Javascript] Cookie  (0) 2020.05.19
[JQuery] Drag & Drop  (0) 2020.04.21
[JQuery] 동적 바인딩 - 댓글달기  (0) 2020.04.21

서버 설정

Servers 생성 확인

 


web-inf 폴더는 내부접근만 가능 (포워드 가능 리다이렉트 불가)


https://127.0.0.1:8085/controller/

 

서버 가동

보안문제

http://localhost:8085/controller/

 


@RequestMapping

@Controller

@component


method=RequestMethod.GET

get 방식으로만 받기

	@RequestMapping(value="/", method=RequestMethod.GET)
	public String home() {
		return "home";
	}

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page session="false"%>
<html>
<head>
<title>Home</title>
</head>
<body>

	<form action="page1" method="get">
		<input type=submit>
	</form>

</body>
</html>

클라이언트 -> 서버 ->디스패쳐 -> 리퀘스트맵핑

 

 

post 방식만 받도록 설정해 놓으면

@Controller
public class HomeController {

	@RequestMapping("/")
	public String home() {
		return "home";
	}
	
	@RequestMapping(value="/page1", method=RequestMethod.POST)
	public String toPage1() {
		return "page1";
	}
	
}


Spring_02.zip
0.02MB

+ Recent posts