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);
}

 

}

 

C. JSP

<%@ 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 { }
 
}

 

@Controller
public class EmployeeListAction {

 

@Autowired
EmployeeDao employeeDao;

 

@RequestMapping("/hr/searchEmp")
public ModelAndView execute(@RequestParam(defaultValue="0") int deptno) throws Exception { }
 
}

 

@Controller
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 { }
 
}

 

@Controller
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( )

 

Interceptor:

추상클래스 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

<bean class="org.mybatis.spring.mapper.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>

 

EmployeeDao.java 인터페이스
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;

}

 

EmployeeMapper.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="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
by 알 수 없는 사용자 2013. 6. 25. 11:24