글
1. Spring Framework에서의 FileUpload
2. Command Pattern을 이용한 PageController 관리
3. Filter & Interceptor
4. Mybatis의 Injection Mapping 기능을 이용하여 Dao 구현클래스 삭제
5. HTML기초
1. Spring Framework에서의 FileUpload
Controller에 관한 객체는 DispatchServlet에서 관여하기 때문에 FileUpload에 대한 것은 dispatch-servlet.xml 설정파일에 등록하여야 한다.
A. dispatch-servlet.xml
(스프링 Docs참고)17 .10.2. Using a MultipartResolver with Commons FileUpload
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="1000000" />
</bean>
* Spring framework 2.5 미만에서는 아래 설정을 따르면 된다.
<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
</bean>
B. Controller
* 파일 경로에 주의 한다
@Controller
@RequestMapping("/upload/upload")
public class FileUploadAction {
@Autowired
ServletContext ctx;
@RequestMapping
public String execute(@RequestParam("name") String name, @RequestParam(value = "age", defaultValue = "0") int age, @RequestParam("photo1") MultipartFile photo1, @RequestParam("photo2") MultipartFile photo2, Model model) throws Exception {
model.addAttribute("name", name);
model.addAttribute("age", age);
File photo1File = getNewFile();
photo1.transferTo(photo1File);
File photo2File = getNewFile();
photo2.transferTo(photo2File);
model.addAttribute("photo1", photo1File.getName());
model.addAttribute("photo2", photo2File.getName());
return "upload/upload";
}
private File getNewFile() {
String repositoryPath = ctx.getRealPath("/files");
String newFileName = "file_" + System.currentTimeMillis() + Math.random();
return new File(repositoryPath + "/" + newFileName);
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>업로드 결과</title>
</head>
<body>
이름: ${name}<br>
나이: ${age}<br>
사진1: ${photo1}<br>
<img src="../files/${photo1}"><br>
사진2: ${photo2}<br>
<img src="../files/${photo2}"><br>
</body>
</html>
2. Command Pattern을 이용한 PageController 관리
Command Pattern: 메서드의 호출을 캡슐화(클래스화) -> 메서드를 클래스화
왜 쓰나?
클래스 하나에 메서드가 계속 추가될 경우 문제점이 발생할 수 있기 때문에 거대화된 클래스의 메서드를 각각 분리
1. 클래스의 변경이 잦은 경우(유지보수 차원에서 메서드의 추가 변경이 잦다)
2. 이 클래스를 사용하는 다른 클래스가 영향을 받을 수 있고, 하나의 클래스에 많은 메서드가 있음으로 가독성이 떨어지게된다.
3. 메서드를 분리하여 각각 클래스화 함으로 문제를 해결
* 만약 한 클래스에 계속 메서드가 추가되는 상황이 발생하게 된다면 커맨드 패턴을 사용해서 클래스로 분리하라
여러 기능을 수행하는 메서드들을 가지고 있는 통합된 Action클래스인 EmployeeController.java
@Controller
@RequestMapping("/hr")
public class EmployeeController {
@Autowired
EmployeeDao employeeDao;
@InitBinder
public void initBinder(WebDataBinder binder) { }
@RequestMapping("/searchEmp")
public ModelAndView list(@RequestParam(defaultValue = "0") int deptno) throws Exception { }
@RequestMapping(value = "/addEmp", method = RequestMethod.GET)
public String addForm() throws Exception { }
@RequestMapping(value = "/addEmp", method = RequestMethod.POST)
public String add(Employee employee, BindingResult result) throws Exception { }
@RequestMapping("/retrieveEmp")
public String retrieve(@RequestParam("empno") int empno, ModelMap modelMap) throws Exception { }
@RequestMapping(value = "/updateEmp", method = RequestMethod.GET)
public String updateForm(@RequestParam("empno") int empno, Model model) throws Exception { }
@RequestMapping(value = "/updateEmp", method = RequestMethod.POST)
public String update(Employee employee, BindingResult result) throws Exception { }
@RequestMapping("/deleteEmp")
public String delete(@RequestParam("empno") int empno) throws Exception { }
}
각각 기능(메서드)을 갖는 클래스로 분리한다
@Controller
public class EmployeeAddAction {
@Autowired
EmployeeDao employeeDao;
@InitBinder
public void initBinder(WebDataBinder binder) { }
@RequestMapping(value="/hr/addEmp",method=RequestMethod.GET)
public String form() throws Exception { }
@RequestMapping(value="/hr/addEmp",method=RequestMethod.POST)
public String add(Employee employee, BindingResult result) throws Exception { }
}
@Controller
public class EmployeeDeleteAction {
@Autowired
EmployeeDao employeeDao;
@RequestMapping("/hr/deleteEmp")
public String execute(int empno) throws Exception { }
}
public class EmployeeListAction {
@Autowired
EmployeeDao employeeDao;
@RequestMapping("/hr/searchEmp")
public ModelAndView execute(@RequestParam(defaultValue="0") int deptno) throws Exception { }
}
public class EmployeeUpdateAction {
@Autowired
EmployeeDao employeeDao;
@InitBinder
public void initBinder(WebDataBinder binder) { }
@RequestMapping(value="/hr/updateEmp", method=RequestMethod.GET)
public String form(int empno, Model model) throws Exception{ }
@RequestMapping(value="/hr/updateEmp", method=RequestMethod.POST)
public String execute(Employee employee, BindingResult result) throws Exception { }
}
public class EmployeeDetailAction {
@Autowired
EmployeeDao employeeDao;
@RequestMapping("/hr/retrieveEmp")
public String execute(@RequestParam("empno") int empno, ModelMap modelMap) throws Exception { }
}
3. Filter & Interceptor(핸들러 인터셉터)
Filter:
인터페이스 javax.servlet.Filter를 구현한 클래스로 다음의 메서드를 갖는다
init(FilterConfig arg0)
doFilter(ServletRequest request, ServletResponse response, FilterChain next)
destroy( )
추상클래스 org.springframework.web.servlet.handler.HandlerInterceptorAdapter를 상속받은 클래스로 다음의 메서드를 갖는다
preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
공통점: PageController의 실행 전,후로 꽂아넣을 수 있는 기능을 수행한다(ex.암호화, 복호화 등..)
차이점: Filter는 FrontController인 DispatchServlet 앞에, Interceptor는 뒤에 위치한다
* 인터셉터 내부 메서드의 실행순서
preHandler() -> Action실행 -> posthandler() -> JSP실행 -> afterCompletion()
* 언제 인터셉터를 사용하나?(인터셉터를 사용하는 예)
Request부터 Response까지의 시간을 측정할 때 사용한다.
어떤 부분이 실행중 일 때 지연시간이 큰지 알아낼 수 있다(인터셉터 내부 메서드 실행순서를 이용)
* 인터셉터를 사용하기 위해서는 dispatch-servlet.xml에 아래와 같이 설정을 등록하여야 한다.
<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list>
<ref bean="testInterceptor"/>
</list>
</property>
</bean>
<bean id="testInterceptor" class="bit.java39.interceptors.TestInterceptor"/>
</beans>
4. Mybatis의 Injection Mapping 기능을 이용하여 Dao 구현클래스 제거
* Dao인터페이스와 Mapper.xml 설정파일만으로 실행 가능하다(Mybatis 3.0이상에서 정상 작동한다)
참고자료: http://mybatis.github.io/spring/mappers.html#scan
MapperScannerConfigurer
<property name="basePackage" value="org.mybatis.spring.sample.mapper" />
</bean>
Dao의 설정에 관여하는 services.xml에 추가하여 사용한다.(Dao의 메서드와 Mapper의 ResultType에 주의)
services.xml에 설정추가
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="bit.java39.dao" />
</bean>
public interface EmployeeDao {
List<Employee> getEmployeeList(int departmentNo) throws Exception;
int insert(Employee employee) throws Exception;
Employee getEmployee(int empNo) throws Exception;
int delete(int empNo) throws Exception;
int update(Employee employee) throws Exception;
}
<?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="bit.java39.dao.EmployeeDao">
<select id="getEmployeeList" resultType="Employee">
select
e.empno as no,
e.ename as name,
e.job,
e.sal as salary,
d.dname as departmentName,
d.loc as departmentLocation,
m.ename as managerName
from emp e
left join dept d on e.deptno=d.deptno
left join emp m on e.mgr=m.empno
</select>
<insert id="insert" parameterType="Employee">
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno)
values (
#{no}, #{name}, #{job}, #{managerNo},
#{hireDate}, #{salary}, #{commission}, #{departmentNo})
</insert>
<select id="getEmployee" parameterType="int" resultType="Employee">
select
empno no,
ename name,
job,
mgr managerNo,
hiredate,
sal salary,
comm commission,
deptno departmentNo
from emp
where empno=#{value}
</select>
<delete id="delete" parameterType="int">
delete emp where empno=#{value}
</delete>
<update id="update" parameterType="Employee">
update emp set
ename=#{name},
job=#{job},
mgr=#{managerNo},
hiredate=#{hireDate},
sal=#{salary},
comm=#{commission},
deptno=#{departmentNo}
where empno=#{no}
</update>
</mapper>
5. HTML
A. Semantic Web(구조화된 웹): 각각 태그에 의미를 부여한다(태그의 용도대로 사용하자)
B. DOM: HTML 엘리먼트를 객체화시켜 tree구조로 관리
C. block 태그: 라인을 점유하는 태그들(라인의 변경)
inline 태그: 라인속에 참여하는 태그들(라인이 바뀌지 않는다)
D. Doctype
block 태그
-> <h*> 헤더태그
-> <p> 문단태그
-> <ol> 순서있는줄태그
-> <ul> 순서없는줄태그
-> <li> 라인아이템태그
-> <div> 분할태그
-> <address> 주소태그
-> <blockquote> 인용문태그
inline 태그
-> <a> 앵커태그
-> <i> 이탤릭체태그
-> <b> 볼드체태그
-> <em> 엠퍼사이즈태그
-> <span> 확장태그
-> <img> 이미지태그
-> <q> 인용문태그
* 각 태그에 대한 자세한 설명은 검색하면 잘 나오므로 알아서 찾아보자.....
'학습정리 > by H2K' 카테고리의 다른 글
node.js, CORDOVA, PhoneGap (0) | 2013.07.11 |
---|---|
javaScript, jQuery 함수 (0) | 2013.07.08 |
NegotiatingViewResolver (0) | 2013.07.07 |
RECENT COMMENT