본 내용은 혼자 공부하기 위하여 다른 포스트를 보면서 저에게 필요한 부분과 궁금했던 부분을 추가하여 게시하는 곳입니다.
궁금한 것에 대한 것은 모르는 것이 많겠지만 함께 알아보도록 노력하겠습니다.
참조 게시 포스트 : http://addio3305.tistory.com/
-------------------------------------------------------------------------------------------------------------------------------------------
1. HandlerMethodArgumentResolver?
스프링 사용 시 컨트롤러에서 파라미터의 값을 가져오거나 수정하는 경우가 있는데 그럴 경우가 있다.
그럴 경우에는 세션에 저장하고 세션에 있던 값을 사용하거나 한다. 하지만 HandlerMethodArgumentResolver를 사용하면 컨트롤러에 도달하기 전에 파라미터를 수정하거나 할 수 있게 해준다.
1.1 CommandMap 생성
우리가 생성했던 SampleController의 메소드들을 살펴보면 파라미터들은 전부 Map 형식인 것을 알 수 있다. 이 형식의 파라미터들은 HandlerMethodArgumentResolver에서 처리하지 않고 스프링의 기본 설정인 ArgumentResolver에서 처리가 된다.
(action-servlet.xml에서 <mvc:annotation-driven />이 선언 되어 있지 않을 경우에 해당)
<mvc:annotation-driven>이 선언되면 map을 사용할 수 없고, 다른 형식을 사용하여야 한다. map을 대신할 commandMap을 만들 것이다.
1) com.mycompany.myapp.common.common 경로에 CommandMap 클래스 생성
2) 하단과 같은 코드를 작성
public class CommandMap { Map<String,Object> map = new HashMap<String,Object>(); public void put(String key, Object value) { map.put(key, value); } public Object get(String key) { return map.get(key); } public boolean isEmpty() { return map.isEmpty(); } public Map<String, Object> getMap(){ return map; } public void clear() { map.clear(); } public boolean containsKey(String key) { return map.containsKey(key); } public boolean containsValue(Object value) { return map.containsValue(value); } public Object remove(String key) { return map.remove(key); } public Set<Entry<String, Object>> entrySet(){ return map.entrySet(); } public Set<String> keySet(){ return map.keySet(); } public void putAll(Map<? extends String, ? extends Object> m) { map.putAll(m); } }
public class CustomMapArgumentResolver implements HandlerMethodArgumentResolver { Logger log = Logger.getLogger(this.getClass()); @Override public Object resolveArgument(MethodParameter para, ModelAndViewContainer mvc, NativeWebRequest webReq, WebDataBinderFactory binderFactory) throws Exception { CommandMap commandMap = new CommandMap(); HttpServletRequest req = (HttpServletRequest)webReq.getNativeRequest(); Enumeration<?> enumeration = req.getParameterNames(); String key = null; String[] values = null; while(enumeration.hasMoreElements()) { key = (String) enumeration.nextElement(); values = req.getParameterValues(key); if(values!=null ) { commandMap.put(key, (values.length>1)? values : values[0]); } } return commandMap; } @Override public boolean supportsParameter(MethodParameter para) { return CommandMap.class.isAssignableFrom(para.getParameterType()); } }
위 클래스는 HandlerMethodArgumentResolver 인터페이스를 구현한 클래스로 2개의 메소드를 구현하였다.
- supportsParameter 메소드
해당 메소드는 바인딩할 클래스를 지정해주는 곳으로 여기서 지정한 클래스를 resolveArgument 메소드에서 처리를 할 수 있다.
- resolveArgument 메소드
해당 메소드는 바인딩된 클래스의 파라미터들을 수정하거나 값을 가져올 수 있는데 여기서 CommandMap 클래스를 새로 만들어 파라미터 안의 값들을 CommandMap에 할당하고 그 값을 리턴하여 준다.
<mvc:annotation-driven> <mvc:argument-resolvers> <bean class="com.mycompany.myapp.common.resolver.CustomMapArgumentResolver" /> </mvc:argument-resolvers> </mvc:annotation-driven>
- mvc:annotation-driven 태그에 mvc:argument-resolvers에 빈 객체를 작성하여 확장 추가하였다.
1.4 테스트
1) 지금까지 만든 것들이 잘 작동하는지 테스트를 하기 위하여 컨트롤러에 다음 부분을 추가한다.
@RequestMapping(value="/testCustomMapArgumentResolver.do") public ModelAndView testCommandMap(CommandMap commandMap) throws Exception{ ModelAndView mv = new ModelAndView(""); if(commandMap.isEmpty()==false) { Iterator<Entry<String, Object>> iterator = commandMap.getMap().entrySet().iterator(); Entry<String,Object> entry = null; while(iterator.hasNext()) { entry = iterator.next(); log.debug("key:"+entry.getKey()+ " , values:"+entry.getValue()); } } return mv; }
위 코드를 살펴보면 다른 테스트와 게시판 목록을 만드는 형식처럼 만들었으며 안의 내용은 반복자를 사용하여 CommandMap의 Entry들을 로그를 이용하여 키 값과 밸류 값을 출력하도록 하였다.
2) 다음으로 주소에 localhost:8080/myapp/testCustomMapArgumentResolver.do?test1=value1&test2=value2 를 입력하였을 때 콘솔 창에 다음과 같은 화면이 뜨면 정상적으로 작동하는 것이다.
'코딩 > Spring' 카테고리의 다른 글
Spring 개발 - 게시판 만들기(11) - 게시글 상세보기 (0) | 2017.12.26 |
---|---|
Spring 개발 - 게시판 만들기(10) - 게시글 쓰기 (0) | 2017.12.25 |
Spring 개발 - 게시판 만들기(8) - 게시판 목록 만들기 (0) | 2017.12.24 |
Spring 개발 - 게시판 만들기(7) - Mybatis 연동하기 (0) | 2017.12.24 |
Spring 개발 - 게시판 만들기(6) - 로그 및 인터셉터 설정 (6) | 2017.12.23 |