** MVC(Model View Controller) 패턴
=> 애플리케이션의 역할을 3가지로 분리해서 구현하는 패턴
=> Model : 비지니스 로직을 처리하고 그 결과를 생성하는 영역
=> View : Model이 생성한 결과를 출력하는 영역
=> Controller : Model 과 View를 연결시켜주는 영역
=> Model2: Presentation Login의 영역의 코드와 Business Logic 영역의 코드를 분리
Java Web Application에서는 Presentation Logic은 jsp 파일에 작성하고 Business Login은 java 파일에 작성
1. 장점
=> 유지보수가 편리
2. 단점
=> 구현이 어려워질 수 있다.
=> Controller를 2단계로 구성
1. FrontController : 클라이언트의 모든 요청을 받아서 처리할려고 하는 Controller
2. PageController : 클라이언트의 요청 1개나 하나의 서비스를 처리하기 위한 Controller
=> Spring 프로젝트 구조
웹 브라우저나 웹 요청(request) -> Web Server(apache) -> Web Application Server(Web Container - tomcat) -> Front Controller -> Page Controller -> Service -> DAO -> DataBase Framework -> 트랜잭션 처리를 위한 Middle Ware -> Database
Web Server의 역할 : 사용자의 요청이 오면 요청에 응답할 수 있는 View를 찾아서 리턴하는 역할, 단순한 HTML로 구성된 것을 요청하면 HTML을 찾아서 리턴해 줄 수 있다.
Web Application Server : Web Server 가 어떤 처리를 요청하면 그 처리를 수행할 수 있는 Servser Application이나 로직을 호출해서 결과를 받은 후 HTMl로 변환해서 Web Server에게 전달
금융업무에서 처럼 온라인 트랜잭션 처리를 많이 하는 곳에서는 DataBase 앞에 별도의 Middle Ware를 추가한다.
실제 업무 처리에서는 Service를 여러 계층으로 분리
** Spring MVC 에서 제공하는 Annotation
1. @Controller, @Service, @Repository, @Component : Bean을 자동 생성해주는 Annotation
2. @Autowired, @Injection, @Resource : 외부에서 자동으로 주입받기 위한 Annotation
3. @RequestMapping
=> Controller 클래스에서 클라이언트의 요청과 호출할 메소드를 매핑해주는 Annotation
4. @RequestParam
=> 클라이언트에서 전달한 파라미터를 매핑하기 위한 Annotation
5. @RequestHeader
=> 클라이언트에서 전달한 해더를 매핑하기 위한 Annotation
6. @PathVariable
=> 디렉토리 패턴에서 URL의 원하는 부분을 추출하기 위해 사용하는 Annotation
7. @CookieValue
=> 쿠키 정보를 매핑하기 위해 사용하는 Annotation
8. @ModelAttribute
=> View에게 데이터를 전달할 때 Annotation
=> 공통된 데이터를 전달하기 위한 목적과 전달되는 파라미터의 이름을 변경하기 위해서 사용
9. @SessionAttribute
=> Session에게 데이터를 저장하기 위한 Annotation
10. InitBinder
=> 파라미터를 수집해서 객체로 만들고자 하는 경우 사용하는 Annotation
11. @ResponseBody
=> 리턴 타입을 HTTP 응답 메세지로 사용하는 Annotation
12. @RequestBody
=> 요청 문자열을 그대로 파라미터로 전달하는 Annotation
** Spring MVC의 주요 구성 요소
1. Dispatcher-Servlet : Front Controller 의 역할, Spring Bean Configuration 파일로 생성
2. Controller : Page Controller의 역할, POJO(다른 외부 프레임워크의 클래스를 상속받지 않은 순수한 자바 객체) 클래스를 만들고 상단에 @Controller라는 어노테이션을 추가해서 생성
3. HandlerMapping : Fornt Controller에서 Page Controller를 선택하도록 해주는 클래스로 직접 생성할 필요가 없다. - Spring이 생성해 줌
4. ModelAndView : Controller 가 처리한 결과를 저장해서 뷰를 선택하도록 하는 정보와 함께 저장하는 클래스
=> 최근에는 잘 사용하지 않는다.
5. ViewResolver : Controller가 리턴한 View이름을 가지고 실제 출력할 View 파일을 결정하는 클래스
=> Forwarding 할 때만 적용되고 Redirect 할 때는 적용되지 않는다.
6. View : 실제 출력될 결과 화면
** Spring MVC Project
1. Spring MVC Project 생성 - Web Application
[File] - [New] - [Spring Project] - [Spring Legacy Project]를 선택하고 [Spring MVC Project]를 선택
=> Project이름을 설정하고 기본 패키지(3 LEVEL이상)를 설정
패키지 이름에서 3번째 부분이 자동으로 Context Path로 설정되고 이 프로젝트를 war 파일로 작성해서 외부에서 열면 그 때는 프로젝트 이름이 Context Path로 설정
2. Spring MVC Project 실행
=> WAS를 설정해서 실행
** Spring MVC Project의 pom.xml 설정 변경
1. properties 태그에서 java 버전과 spring 버전을 설정
=> properties 태그는 하단에서 자주 사용할 문자열을 이름으로 등록해 놓은 태그
=> java version은 1.8 이상으로 설정하는 것이 일반적 : 람다와 스트림 API를 1.8 버전부터 사용 가능
=> Spring version은 4버전 이상으로 설정하는 것이 일반적 : Spring4 부터 RestController를 제공
REST API : 동일한 서비스를 제공하는 URL은 모두 동일해야 한다. 일반적으로 요청을 하면 JSON이나 XML로 응답을 해서 클라이언트에서 파싱을 해서 뷰를 만들어내는 방식
![]() |
2. repositories
=> Maven 중앙 저장소가 아닌 곳에서 외부 라이브러리를 다운로드 받고자 하는 경우 설정하는 태그
=> oracle을 사용할 때만 우리는 사용
=> 기업에서는 기업별로 별도의 저장소가 만들어져 있고 그 곳을 설정
3. dependencies
=> 사용할 외부라이브러리의 의존성(외부 라이브러리를 다운로드 받고 자동으로 build path에 추가)을 설정
=> node.js 나 최근의 프레임워크들은 대부분 이 방식을 이용해서 외부 라이브러리의 의존성을 설정
=> junit의 버전을 4.12 이상으로 변경 - Spring 5.0 이상에서는 junit 이 4.12 이상인 경우에만 Test 가능
junit - 단위 테스르를 지원하는 자바 라이브러리
![]() |
1) 단위 테스트를 수행하고자 하면 Spring Test라이브러리가 잇어야 한다.
=> Sprint-test 라이브러리의 의존성을 추가
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
</dependency>
2) HttpServlet 과 jsp 버전을 변경
HttpServlet : JavaEE에서 제공하는 URL 요청에 응답할 수 있는 Java Class, WAS가 호출할 수 있는 클래스
JSP(Java Server Pages) : HttpServlet에 출력을 쉽게 할 수 있도록 만든 클래스인데 HTMl의 Java코드를 스크립트 형태로 삽입해서 작성하는 것으로 요청이 오면 HttpServlet 클래스로 변환
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.serverlet.jsp-api</artifactId>
<version>2.3.0</version>
</dependency>
4. build 태그 안의 configuration에서 source와 target 변경 - 1.6에서 1.8로 변경
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
pom.xml 파일
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.pk</groupId>
<artifactId>mvc</artifactId>
<name>SpringMVC</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<java-version>1.8</java-version>
<org.springframework-version>5.0.7.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.test.int1.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
5. 실행
6. 실제 업무 Project를 진행할 때는 1~4까지는 직접 수행하지 않을 것이다.
=> Spring MVC Project 는 대부분의 경우 여러 개발자가 같이 진행하는 경우가 많아서 한명이 모든 프로젝트 설정을 하고 설정에 대해서 설명한 후 프로젝트를 복사한 후 동일한 설정에서 작업을 진행
7. 톰캣을 이용해서 실행 한 경우 포트문제 때문에 실행이 안될 때
=> 오라클과 톰캣 모두 기본 설정 포트가 8080이라서 문제가 됨
Servers 디렉토리에서 server.xml 파일을 열어서 8080을 다른 포트로 변경
=> 포트번호가 음수로 설정된 경우
<Server post="8005" shutdown="SHUTDOWN"> 이 태그에 port 번호가 -1로 설정된 경우에는 8005번으로 변경
server.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
--><!-- Note: A "Server" is not itself a "Container", so you may not
define subcomponents such as "Valves" at this level.
Documentation at /docs/config/server.html
--><Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
<!-- Security listener. Documentation at /docs/config/listeners.html
<Listener className="org.apache.catalina.security.SecurityListener" />
-->
<!--APR library loader. Documentation at /docs/apr.html -->
<Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener"/>
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>
<!-- Global JNDI resources
Documentation at /docs/jndi-resources-howto.html
-->
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
</GlobalNamingResources>
<!-- A "Service" is a collection of one or more "Connectors" that share
a single "Container" Note: A "Service" is not itself a "Container",
so you may not define subcomponents such as "Valves" at this level.
Documentation at /docs/config/service.html
-->
<Service name="Catalina">
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
<!--
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
-->
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
-->
<Connector connectionTimeout="20000" port="9000" protocol="HTTP/1.1" redirectPort="8443"/>
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
-->
<!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443
This connector uses the NIO implementation. The default
SSLImplementation will depend on the presence of the APR/native
library and the useOpenSSL attribute of the
AprLifecycleListener.
Either JSSE or OpenSSL style configuration may be used regardless of
the SSLImplementation selected. JSSE style configuration is used below.
-->
<!--
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
type="RSA" />
</SSLHostConfig>
</Connector>
-->
<!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
This connector uses the APR/native implementation which always uses
OpenSSL for TLS.
Either JSSE or OpenSSL style configuration may be used. OpenSSL style
configuration is used below.
-->
<!--
<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
maxThreads="150" SSLEnabled="true" >
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
<SSLHostConfig>
<Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
certificateFile="conf/localhost-rsa-cert.pem"
certificateChainFile="conf/localhost-rsa-chain.pem"
type="RSA" />
</SSLHostConfig>
</Connector>
-->
<!-- Define an AJP 1.3 Connector on port 8009 -->
<!--
<Connector protocol="AJP/1.3"
address="::1"
port="8009"
redirectPort="8443" />
-->
<!-- An Engine represents the entry point (within Catalina) that processes
every request. The Engine implementation for Tomcat stand alone
analyzes the HTTP headers included with the request, and passes them
on to the appropriate Host (virtual host).
Documentation at /docs/config/engine.html -->
<!-- You should set jvmRoute to support load-balancing via AJP ie :
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
-->
<Engine defaultHost="localhost" name="Catalina">
<!--For clustering, please take a look at documentation at:
/docs/cluster-howto.html (simple how to)
/docs/config/cluster.html (reference documentation) -->
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
<!-- Use the LockOutRealm to prevent attempts to guess user passwords
via a brute-force attack -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
</Realm>
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t "%r" %s %b" prefix="localhost_access_log" suffix=".txt"/>
<Context docBase="SpringMVC" path="/mvc" reloadable="true" source="org.eclipse.jst.jee.server:SpringMVC"/></Host>
</Engine>
</Service>
</Server>
** Spring MVC Project의 구조
1. pom.xml을 제일 먼저 읽어서 실행
=> 이 파일의 내용이 잘못되면 애플리케이션은 실행되지 않는다.
=> pom.xml을 수정하면 저장한 후 애플리케이션을 다시 실행해서 잘못된 부분이 있는지 확인
2. web.xml(java web application 설정 파일)을 읽어서 애플리케이션 설정
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
=> listener는 애플리케이션이 시작되거나 종료될 때는 또는 세션이 생성되거나 소멸될 때 등의 이벤트가 발생하면 호출될 클래스를 설정 : 이벤트가 발생했을 때 호출되는 객체를 Listener라고 한다.
=> spring mvc project에서 listener 설정만 있는 경우에는 applicationContext.xml 파일이 Listener역할을 수행한다.
=> context-param 태그를 이용해서 applicationContext.xml 파일의 경로를 변경할 수 있다.
contextConfiguration 이라는 이름에 파일 경로를 설정하면 된다.
=> 이 파일에는 공통으로 사용할 bean에 대한 정보를 설정한다.
<!-- 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>
=> servlet-mapping에서는 요청을 처리할 HttpServlet 클래스를 설정
/는 .jsp 를 제외한 모든 요청
=> Spring의 DispatcherServlet은 Front-Controller의 역할을 수행
그 안에 있는 init-param이 DispatcherServlet의 설정 내용을 가지는 파일의 경로를 설정
3. URL 패턴
1) /*: 모든 요청에 해당하는 패턴, 이 패턴은 파라미터 인코딩 설정에 이용
2) /: .jsp를 제외한 모든 요청을 처리
=> 1)과 2)로 설정을 하게되면, .js, .css, .png 와 같은 리소스 요청도 전부 처리할려고 한다.
외부에 자원을 두지 않고 프로젝트 내에 자원을 사용하는 경우에 이데 대한 해결책을 설정해야 한다.
3) *.확장자 : 특정한 확장자로 끝나는 요청을 처리, 예전에는 확장자를 do로 처리를 많이 했음, 아직도 공공기관 이나 Naver 와 같은 곳에서는 사용
4)/디렉토리/*: 특정한 디렉토리가 포함된 요청을 처리, 최근에 이 디렉토리에 서비스 이름을 이용하고 뒤에 작업 내용을 설정하는 형태로 서비스를 구현하는 곳이 많음
5)/디렉토리/요청경로: 구체적으로 하나의 요청을 지정, 거의 사용하지 않음
4. Encoding Filter 설정
=> post 방식으로 전송된 파라미터는 인코딩을 해서 읽어야 한다.
인코딩을 하지 않으면 한글이 깨지게 된다.
=> java web programming에서는 파라미터를 읽기 전에 HttpServletRequest 객체를 가지고 setCharacterEncoding("utf-8") 메소드를 호출해야 한다.
=> spring mvc project에서는 web.xml 파일에 filter를 설정해서 모든 요청을 처리하기 전에 위의 메소드를 호출하도록 설정하는 것이 일반적이다.
** Controller
=> MVC 패턴의 Controller는 사용자의 요청을 받아서 필요한 Business Login(Service)을 호출하고 그 결과를 받아서 View에 전달하는 역할을 수행하는 객체
=> Java Web Programming에서는 HttpServlet클래스를 이용해서 생성하고 Spring MVC Project에서는 POJO클래스를 만들고 클래스 상단에 @Controller를 추가해서 생성
@Controller가 추가된 클래스는 spring 설정 파일의 base package 안에 만들어져야 한다.
1. 요청 처리 방법
=> Controller 안에 메소드를 생성하고 위에
@RequestMapping(value = "요청할 URL", method = RequestMethod.GET or POST)
를 추가하면 URL 요청이 GET 이나 POST로 왔을 때 메소드를 호출한다.
=> 요청방식에 상관없이 호출할 것이면 @RequestMapping("요청할 URL")의 형식으로 설정하는 것도 가능하다.
=> 여러 개의 요청을 한꺼번에 처리하고자 하면 value={URL, URL...}으로 설정
2. 파라미터 처리 방법 : 요청 처리 메소드의 매개변수로 설정
datail?num = 1
=> 기존의 HttpServletRequest 클래스를 이용
getParameter나 getParameterValues 메소드를 호출해서 처리
요청처리 메소드(HttpServletRequest.request){
int num = Integer.parseInt(request.getParameter("num"));
}
=> @RequestParam 이용
@RequestParam("파라미터 이름") 자료형 변수명
자료형변환이 자동으로 이루어 진다.
요청 처리 메소드(@RequestParam("num") int num){
}
=> Command 객체를 이용
파라미터로 구성된 Class를 만들어서 클래스의 변수를 매개변수로 받으면 파라미터들이 Command 클래스의 프로퍼티에 자동으로 대입된다.
파라미터 이름과 프로퍼티 이름이 같아야 한다.
3. 파라미터 처리 실습
1) home.jsp 파일에 링크 추가
=> 기존의 파일을 삭제하고 다시 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MVC 실습</title>
</head>
<body>
<a href="form">파라미터 입력</a><br/>
</body>
</html>
2) HomeController 클래스에 form 요청이 GET으로 왔을 때 처리하는 메소드를 생성
package com.my.MVC;
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;
/**
* Handles requests for the application home page.
*/
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
/**
* Simply selects the home view to render by returning its name.
*/
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(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";
}
//form 요청을 GET으로 전송했을 때 처리할 메소드
@RequestMapping(value="form", method=RequestMethod.GET)
public String form() {
//단순 페이지 이동은 jsp 파일의 이름만 리턴하면 된다.
return "form";
}
}
3) WEB-INF/views 디렉토리에 form.jsp 파일을 만들고 작성
=> 웹 사이트만 만드는 경우에는 form을만들고 전송 버튼을 만들어서 전송을 하면 되고 모든 디바이스에 요청을 처리하는 서버를 만들 때는 ajax로 요청을 전송해야 한다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>파라미터 전송</title>
</head>
<body>
<!-- action을생략하면 이 페이지에 오게된 요청 : form, method는 생략하면 get
enctype은 file이 있을 때만 multipart/form-data를 설정 -->
<form id="paramform" action="" method="post">
이름:<input type="text" name="name" id="name"/><br/>
전화번호:<input type="text" name="phone" id="phone"/><br/>
나이:<input type="text" name="age" id="age"/><br/>
<input type="submit" value="전송"/>
<input type="button" value="전송" id="ajaxbtn"/>
</form>
</body>
</html>
4) 애플리케이션을 실행해서 입력화면까지 이동하는지 확인
5) HomeController 클래스에 form 요청을 post로 전송한 경우 처리할 메소드를 생성
package com.my.mvc;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
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;
@Controller
public class NyController {
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
return "home";
}
//form 요청을 GET으로 전송했을 때 처리할 메소드
@RequestMapping(value="form", method=RequestMethod.GET)
public String form() {
//단순 페이지 이동은 jsp 파일의 이름만 리턴하면 된다.
return "form";
}
/*
@RequestMapping(value="form", method= RequestMethod.POST)
//기존의 HttpServletRequest를 이용한 파라미터 처리를 위한 메소드
public String form(HttpServletRequest request) {
String name = request.getParameter("name");
String phone = request.getParameter("phone");
String age = request.getParameter("age");
//출력
System.out.println("이름:" + name);
System.out.println("전화번호:" + phone);
System.out.println("나이:" + age);
return "result";
*/
@RequestMapping(value="form", method= RequestMethod.POST)
//@RequestParam을 이용한 파라미터 처리를 위한 메소드
//Spring에서 파라미터 처리를 할 때 많이 사용하는 방법
public String form(
@RequestParam("name") String name,
@RequestParam("phone") String phone,
@RequestParam("age") int age) {
//출력
System.out.println("이름:" + name);
System.out.println("전화번호:" + phone);
System.out.println("나이:" + age);
return "result";
}
}
7) command 객체를 이용하는 방법
=> name과 phone과 age를 저장할 수 있는 Commande Class를 생성
=> 자료형과 이름을 잘 맞추어야 한다.
getter & setter와 toString을 해준다.
package com.my.mvc.domain;
public class User {
private String name;
private String phone;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [name=" + name + ", phone=" + phone + ", age=" + age + "]";
}
}
=> 요청처리 메소드를 수정
package com.my.mvc;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
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 com.my.mvc.domain.User;
@Controller
public class HomeController {
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
return "home";
}
//form 요청을 GET으로 전송했을 때 처리할 메소드
@RequestMapping(value="form", method=RequestMethod.GET)
public String form() {
//단순 페이지 이동은 jsp 파일의 이름만 리턴하면 된다.
return "form";
}
/*
@RequestMapping(value="form", method= RequestMethod.POST)
//기존의 HttpServletRequest를 이용한 파라미터 처리를 위한 메소드
public String form(HttpServletRequest request) {
String name = request.getParameter("name");
String phone = request.getParameter("phone");
String age = request.getParameter("age");
//출력
System.out.println("이름:" + name);
System.out.println("전화번호:" + phone);
System.out.println("나이:" + age);
return "result";
*/
/*
@RequestMapping(value="form", method= RequestMethod.POST)
//@RequestParam을 이용한 파라미터 처리를 위한 메소드
//Spring에서 파라미터 처리를 할 때 많이 사용하는 방법
public String form(
@RequestParam("name") String name,
@RequestParam("phone") String phone,
@RequestParam("age") int age) {
//출력
System.out.println("이름:" + name);
System.out.println("전화번호:" + phone);
System.out.println("나이:" + age);
return "result";
*/
@RequestMapping(value="form", method= RequestMethod.POST)
//Command 객체를 이용하는 방법
public String form(User user) {
//출력
System.out.println(user);
return "result";
}
}
4.@PathVariable
=> 최근의 상세보기 구현에서는 파라미터를 사용하지 않는 경우가 있다.
=> 디렉토리 패턴에서 사용하는데 /데이터의 형식으로 넘겨줍니다
=> 블로그 형 게시판에서 많이 사용
=> Spring의 Controller에서 마지막 부분을 읽어내고자 할 때 사용하는 어노테이션이 @PathVariable
@RequestMapping(value="디렉토리이름/{변수명}")
요청처리메소드(@PathVariable("변수명") 자료형 지역변수이름)
http://myitis5212.tistory.com/351 의 경우
@RequestMapping(value="{num}")
요청처리메소드(@PathVariable("num") int num)
5. PathVariable 실습
1) home.jsp 파일에 요청 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MVC 실습</title>
</head>
<body>
<a href="form">파라미터 입력</a><br/>
<a href="detail/170">Path Variable</a><br/>
</body>
</html>
2) HomeController 클래스에 위의 요청을 처리하는 메소드를 생성
package com.my.mvc;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.my.mvc.domain.User;
@Controller
public class HomeController {
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
return "home";
}
//form 요청을 GET으로 전송했을 때 처리할 메소드
@RequestMapping(value="form", method=RequestMethod.GET)
public String form() {
//단순 페이지 이동은 jsp 파일의 이름만 리턴하면 된다.
return "form";
}
/*
@RequestMapping(value="form", method= RequestMethod.POST)
//기존의 HttpServletRequest를 이용한 파라미터 처리를 위한 메소드
public String form(HttpServletRequest request) {
String name = request.getParameter("name");
String phone = request.getParameter("phone");
String age = request.getParameter("age");
//출력
System.out.println("이름:" + name);
System.out.println("전화번호:" + phone);
System.out.println("나이:" + age);
return "result";
*/
/*
@RequestMapping(value="form", method= RequestMethod.POST)
//@RequestParam을 이용한 파라미터 처리를 위한 메소드
//Spring에서 파라미터 처리를 할 때 많이 사용하는 방법
public String form(
@RequestParam("name") String name,
@RequestParam("phone") String phone,
@RequestParam("age") int age) {
//출력
System.out.println("이름:" + name);
System.out.println("전화번호:" + phone);
System.out.println("나이:" + age);
return "result";
*/
@RequestMapping(value="form", method= RequestMethod.POST)
//Command 객체를 이용하는 방법
public String form(User user) {
//출력
System.out.println(user);
return "result";
}
@RequestMapping(value="detail/{num}", method= RequestMethod.GET)
//경로를 변수로 이용하고자 할 때 읽어내는 방법 : 최근의 블로그형 게시판에 이용
public String detail(@PathVariable("num") int num){
//출력
System.out.println(num);
return "result";
}
}
6. ModelAttribute
=> Controller 클래스의 메소드 위에 이 어노테이션을 설정하고 메소드가 리턴을 하면 메소드의 리턴되는 데이터가 모든 View에 전송된다.
@ModelAttribute("msg")
public String result(){
return "Hello Common String"
}
이 메소드가 있는 Controller 의 모든 View에게는 msg라는 이름으로 Hello Common String이 attribute로 전달되게 된다.
=> Command 객체로 파라미터로 받으면 Command객체로 받은 내용이 다음 Viw에게 클래스 이름의 첫글자를 서문자로 변경한 것으로 전송되는데 이 때 이름을 변경해서 넘기고자 하면 Command 객체 앞에 @ModelAttribute("별명") 클래스 변수명 의 형태로 받으면 된다.
=> Commmand 객체 : 파라미터들을 묶어서 전송받기 위한 클래스의 객체
Spring에서 유효성 검사 할 때 유용하게 사용된다.
=> 유효성 검사는 클라이언트와 서버 모두에게 하게 되는데 서버에서 유효성 검사를 한 경우 유효성 검사에 실패했을 때 기존의 데이터를 어떻게 넘겨줄 것인가가 어려운데 Spring에서는 Command 객체를 이용해서 해결
7. InitBinder
=> 메소드 위에 @InitBinder를 추가하고 데이터 형식을 설정하면 형식에 맞는 데이터가 오면 자동 변환을 해준다.
@InitBinder
pulbic void initBinder(WebDataBinder binder) {
SimpleDateFormat sdf = new SimpleDateFormat("날짜 형식");
Biner.registerCustomEdirot(java.util.Date.class, new CustomDateEditor(sdf, false));
}
=> 날짜 형식의 문자열이 오면 java.utilDate 형식으로 변환을 해준다.
8. @DateTimeFormat
=> Command 객체의 클래스를 만들 때 Date타입이 있는 경우 Date 타입 위에 @DateTimeFormat(patter="날짜형식"
package com.my.mvc.domain;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
public class User {
private String name;
private String phone;
private int age;
//월2자리/일2자리/년도4자리 형식의 문자열로 입력해도 Date로 변환
@DateTimeFormat(pattern="MM/dd/yyyy")
private Date birthday;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [name=" + name + ", phone=" + phone + ", age=" + age + "]";
}
}
9. Controller 요청 처리 메소드의 매개변수
=> Java Web Application 의 HttpServlet의 요청 처리 메소드는 HttpServletRequest, HttpServletResponse 2개의 매개변수를 가지고 있다.
=> Spring에서는 요청 처리 메소드의 매개변수를 다양한 형태로 만들 수 있다.
1) HttpServletRequest와 HttpServletResponse 사용 가능
2) HttpSession 사용 가능
3) Locale : 현재 요청에 대한 지역(국가 설정) 정보
4) Reader, Writer : 일고 쓰기를 스트림을 이용해서 직접 하고자 할 때 사용
5) Map, Model, ModelMap : View 페이지에 데이터를 전송하고자 할 때 사용
6) @RequestParam,@RequestHeader
=> 파라미터나 헤더 정보를 받고자 할 때 사용
=> @RequestHeader는 OpenAPI 서버를 직접 고현하고자 할 때 사용
7) @CookieValue
=> 쿠키 값을 읽어내고자 할 때 사용
=> 보안 문제 때문에 사용하지 않는 것을 권장했다가 최근에 사용자의 요청흐름을 파악할 때 쿠키를 이용하는 경우가 많아져서 다시 중요
8) @PathVariable
=> URL에 변수를 추가한 형태일 때 변수를 읽기 위한 파라미터
9) Errors, BindResult : 데이터 유효성 검사를 할 때 사용
10) Command 객체
11) @RedirectAttribute : 리다이렉트할 때 1번만 전달되는 데이터를 생성할 때 사용
10. Controller의 요청 처리 메소드의 리턴 타입
1) ModelAndView : 출력할 뷰 이름과 출력할 데이터를 1개로 묶어주는 클래스
2) Model, Map : 출력할 데이터만 생성해서 리턴, 뷰이름은 요청 URL로 설정
3) String : 뷰 이름을리턴, 출력할 데이터가 있으면 메소드의 매개변수로 Map 이나 Model을 만들어서 저장
4) View : 뷰를 직접 만들어서 춫력 - 파일 다운로드 같은 곳에서 이용
5) void : 요청과 동일한 이름의 뷰로 출력할 때 사용 - 단순 페이지 이동에 사용
6) VO 나 DTO 또는 List : JSON 출력하고자 하는 경우 사용
7) HttpHeaders : 단순하게 헤더만 만들어서 전송하고자 할 때 사용 - API 요청이 실패했을 때
8) ResponseEntity : Http헤더와 내용을 가공하조가 할 때 사용
=> 3번과 5번, 6번이 초반에는 중요
11. View 설정
=> 출력할 뷰는 Controller에서 리턴한 문자열과 ViewResolver 설정을 합쳐서 결정
=> 기본 이동방법은 Forwarding
=> ViewResolver 설정은 appServlet 디렉토리에 spring 설정 파일에 존재
<!-- ViewResolver 설정
Controller에서 forwarding 하라고 view 이름을 리턴하면,여기 조합과 연산을 해서 실제 출력할 뷰를 결정 -->
<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>
=> 시작 요청의 경우는 / 이외에 index.html 까지 처리해주는 것이 일반적
=> redirect를 하고자 하는 경우에는 view 이름 앞에 redirect: 를 추가
=> redirect를 하게되면 ViewResplver와 관계없이 동작
redirect를 사용할 때는 외부 도메인으로 가던가 Controller로 다시 돌아오도록 해야 한다.
redirect할 때 특정 View 페이지르 직접 이동하지 않도록 해야 한다.
위의 경우가 URL에 jsp가 보이게 되는 이유이다.
=> redirect 하는 경우는 작업을 수행한 경우이고 forwarding 하는 경우는 조회를 하는 경우이다.
=> 웹페이지를 만드는 것이 아니라면 전부 forwarding이다.
iOS, Android, Web Browser 요청을 하나의 서버에서 하고자 하면 뷰를 보여주는 것이 아니고 데이터를 리턴하는 경우이다.
Web Browser에서는 전부 ajax로 요청하고 javascript 코드를 이용해서 페이지 이동을 해야 한다.
=> 웹 애플리케이션을 기획할 때 하나의 서버 애플리케이션을 모두 지원하고자 하면 AJAX 요청을 잘 이해해야 하고 웹 사이트와 모바일 서버를 별도로 만든다면 AJAX는 유효성 검사만 할 수 있어도 된다.
12. Controller에서 View에게 데이터 전달 : Attribute
1) Model이나 Map을 요청처리 메소드의 매개변수로 마들고 이 매개변수에 데이터를 저장하면 request의 attribute로 만들어져서 전달된다.
2) 리턴 타입을 ModelAndView로 만들어서 ModelAndView에 데이터를 저장하고 리턴해주면 request의 attribute로 만들어져서 전달된다.
3) @ModelAttrobute가 붙은 데이터도 View에게 전달된다.
4) Command 객체
5) Session에 저장하는 방법
=> HttpSession을 생성해서 저장
=> RedirectAttributes 를 이용해서 한 번만 사용하는 데이터를 생성해서 전달
** Spring MVC Project를 위한 데이터베이스 테이블을 생성
=> Oracle 과 MyBatis 연동 => Hibernate로 변경 => MySQL로 변경
1. Oracle에 작성
drop table item;
CREATE TABLE ITEM(
itemid number(5),
itemname VARCHAR2(20),
price number(6),
description VARCHAR2(50),
pictureurl VARCHAR2(20),
PRIMARY KEY (itemid)
);
insert into item values(1, 'Lemon', 500, 'Vitamin-A', 'lemon.jpg');
insert into item values(2, 'Orange', 1500, 'Vitamin-B', 'orange.jpg');
insert into item values(3, 'Kiwi', 2000, 'Vitamin-C', 'kiwi.jpg');
insert into item values(4, 'Grape', 1000, 'Vitamin-D', 'grape.jpg');
insert into item values(5, 'Strawberry', 2000, 'Vitamin-E', 'strawberry.jpg');
insert into item values(6, 'Mandarin', 300, 'Vitamin-F', 'mandarin.jpg');
commit;
select * from ITEM;
=> 오라클은 테이블 이름과 컬럼 이름을모두 대문자를 사용 : DTO를 만들지 않고 Map을 이용하면 중요
2. MySQL에 작성
-- 테이블이 존재하면 삭제
drop table item;
-- 테이블 생성
-- 데이터를 삽입하고 삭제하고 갱신하는 일이 빈번하면 innodb
-- 주로하는 일이 조회라면 MyISAM(Indexed Sequential Access Media) 으로 설정
-- 한글이 있으면 인코딩 설정을 해주어야 한다.
CREATE TABLE ITEM(
itemid int,
itemname VARCHAR(20),
price int,
description VARCHAR(50),
pictureurl VARCHAR(20),
PRIMARY KEY (itemid)
)engine=innodb default charset=utf8;
insert into item values(1, 'Lemon', 500, 'Vitamin-A', 'lemon.jpg');
insert into item values(2, 'Orange', 1500, 'Vitamin-B', 'orange.jpg');
insert into item values(3, 'Kiwi', 2000, 'Vitamin-C', 'kiwi.jpg');
insert into item values(4, 'Grape', 1000, 'Vitamin-D', 'grape.jpg');
insert into item values(5, 'Strawberry', 2000, 'Vitamin-E', 'strawberry.jpg');
insert into item values(6, 'Mandarin', 300, 'Vitamin-F', 'mandarin.jpg');
commit;
select * from ITEM;
=> MySQL은 테이블이름이나 컬럼이름을 소문자로 사용
컴파일 하는 언어의 실행 과정
소스코드 -> Compile(문법 체크) -> 실행되기 직전의 코드(자바는 Byte Coce) -> build(애플리케이션이 실행할 수 있도록 각 운영체제의 start up 코드난 실행되기 직전의 코드를 모아서 실행 가능한 프로그램으로 생성) -> target version을 설정) -> load(메모리에 적재) -> run(실행)
컴파일 언어의 IDE들은 대부분 코드를 수정하고 새로 만들면 자신이 컴파일을 해서 문법적인 오류를 체크
Server 애플리케이션은 하나의 Computer에서 실행되기 때문에 이행을 하지 않는 한 그다지 중요하지 않다.
스크립트 언어
=> 줄 단위로 번역하면서 실행
=> 문법적인 에러체크를 하지 않고 실행하면서 에러를 발생시킨다.
=> javaScript, Python, Kotlin, Swift 등
=> Caching
재사용을 빠르게 하기 위해서 로컬에 저장해 두는 것
** Filter - spring에서는 Interceptor, AOP(관점 지향 프로그래밍 - 작업의 종류에 따라 프로그래밍을 분리 - 비지니스 로직처리와 공통 관심 사항으로 분리)
=> 요청을 처리하기 전에 수행할 작업이나 요청을 처리한 후에 수행할 작업을 설정하는 객체
실제로 만들어야 하는 것은 클래스
IoC(제어의 역전) : 개발자가 클래스를 만들어서 비지니스 로직만 작성을 하면 수명주기와 같은 관리작업은 프레임워크나 컨테이너가 하도록 객체 생성을 프레임워크나 컨테이너가 수행하는 것
=> Filter를 가지고 작업할 때 결과를 내가 원하는 자료형으로 변경하는 Filter를 만들기도 하는데 이 경우에는 Wrapper라고 부른다.
Web에서 요청을 전송 방식
1. GET
=> 파라미터를 URL 뒤에 붙여서 전송하는 방식
=> 보안이 취약하고 보내는 파라미터 크기에 제한이 있다.
=> 요청을 전송하는 기본 방식이다.
2. POST
=> 파라미터를 Header에 숨겨서 전송하는 방식
=> 보안이 우수하고 파라미터 크기에 제한이 없다.
=> form에 post라고 설정을 하거나 ajax 요청을 할 때 post라고 설정을 해야 한다.
** 파라미터 생성
=> parameter : 웹에서 요청을 전송할 때 서버에게 전달하는 데이터
1. URL 뒤에 ?를 추가하고 파라미터이름=값, 파라미터이름=값 의 형태로 직접 작성할 수 잇다.
이 경우는 무조건 GET 방식 으로 전송되는데 목록보기에서 상세보기를 만들 때 많이 이용
2. form을 만들고 안에 입력 가능한 객체들을 생성해서 전송하는 방법
=> 전송할 객체들은 name 속성에 서버에서 이용할 이름을 생성해야 한다.
=> 전송 방식으로 GET, POST로 설정하는 것이 가능
=> input에 file, password 그리고 textarea 태그가 있으면 반드시 전송방식은 post
=> file이 있는 경우에는 enctype을 multipart/form-data로 설정