우리는 페이지 구현하면서 종종 redirect를 해줄 경우가 있다.
하지만, 대부분 parameter들을 url뒤에 붙여서 get방식으로 값을 넘겨준다.
이번에 다룰 내용에서는 redirect post를 다룰 예정이다.
바로 RedirectAttributes의 addFlashAttribute 를 이용하여 post방식처럼 url뒤에 parameter를
추가하지 않아도 화면에 값을 받을수 있다.
그.러.나 jsp 페이지의 requestmapping 컨트롤러에서도 값을 받을수 있나 확인해봤는데 -_- view 페이지에서만 출력이 되더라...
이건 조금더 확인해봐야할듯..
그렇다면 임의로 컨트롤러 2개를 만들어서 테스트를 해보도록 합시다요
1. 우선은 redirect페이지를 호출해줄 컨트롤러가 필요하겠죠
@RequestMapping(value="/redirectPostTest") public String redirectPostTest(RedirectAttributes redirectAttr) { redirectAttr.addFlashAttribute("param1", "나의파람"); return "redirect:/listTest"; }
2. 마지막으로 redirect페이지인 컨트롤러 와 뷰를 생성해주어야 하겠고요
위 redirect 컨트롤러에서 redirect 해주는 mapping url이 listTest이니까 컨트롤러에
하나 추가를 해주고
@RequestMapping(value="/listTest") public String listTest() { return "listTest"; }
return view page인 listTest.jsp 페이지에 다음과 같이 태그추가를 해보도록 하시고
실행을 해보도록 하시죠.
redirect 데이터 :: ${param1 }
http://localhost:8080/redirectPostTest 라고 준결과 페이지다.
redirect url로 정상적으로 가면서도 url 뒤에는 어떠한 parameter도 붙지 않고 redirectPostTest
URL에서 SET해준 값을 정상적으로 받을수 있었다.
여기서 주의할 사항은 addFlashAttribute에 대한 set은 한개만 되는거 같다.
addFlashAttribute 를 2개의 데이터를 set하였을때 넘겼을 경우 두가지 데이터 모두 null이 떨어지는것이
확인 되었다.
그렇다면 여러개의 데이터를 받고싶을 경우는 어떻게 해야 할까?
정답은 아니더라도 본인이 생각한 임시방편은 -_- map객체에 여러개의 값을 담아서 전송했다.
대부분 넘기고자 하는 parameter들의 타입들이 int,string과같은 단일 변수이라 가정하고 구현한것임.
addFlashAttribute를 두번 이용하여 데이터를 전달하였을때의 결과
//redirectPostTest 컨트롤러에 다음과 같이 코드 추가 @RequestMapping(value="/redirectPostTest") public String redirectPostTest(RedirectAttributes redirectAttr) { redirectAttr.addFlashAttribute("param1", "나의파람"); redirectAttr.addFlashAttribute("param2", "나의파람2"); return "redirect:/listTest"; }
jsp페이지(body태그에 넣음)
redirect 데이터(1) -> ${param1 } redirect 데이터(2)-> ${param2 }
실행결과화면
하나라도 나올줄 알았는데 값이 모두 안찍힘;;
addFlashAttribute를 한번 이용하되 arraylist에 데이터를 담아 전달하였을때의 결과
@RequestMapping(value="/redirectPostTest") public String redirectPostTest(RedirectAttributes redirectAttr) { Map<String, Object> map = new HashMap<String,Object>(); map.put("param1", "나의파람1"); map.put("param2", "나의파람2"); redirectAttr.addFlashAttribute("param1", map); return "redirect:/listTest"; } @RequestMapping(value="/listTest") public String listTest() { return "listTest"; }
jsp페이지(body태그에 넣음)
redirect 데이터(1) -> ${param1.param1 }
redirect 데이터(2)-> ${param1.param2 }
실행결과화면
잘나온다..
이번포스팅에서는 redirect post방식을 알아보았다.
도움이 되셨다면 공감클릭! 궁금하신점은 댓글!!
class파일내에서 classpath에 존재하는 리소스 파일읽어오기 (0) | 2014.07.30 |
---|---|
스프링3(Spring3) - 메이븐(maven) pom.xml에서 오라클 JDBC(ojdbc14.jar) 라이브러리 추가하기 (0) | 2014.07.30 |
스프링3(Spring3) - @ResponseBody + jackson을 이용하여 심플하게 JSON 구현하기 (0) | 2014.07.30 |
스프링3(Spring3) - 인터셉터(interceptor) 설정 (4) | 2014.07.28 |
스프링3(Spring3) - SQL 쿼리 출력을 위한 로그레벨 설정 (0) | 2014.07.27 |
기존에 Spring프로젝트를 하면서 jackson json이 있는거는 알고 설정법까지 알고 있었지만
기존 json 파싱 라이브러리와 별차이없을거라 생각하고 대수롭지 않게 생각했었다.
json-simple이나 json json-lib + ezmorph 를 사용하여 json object를 생성햇었다..
하지만 포스팅을 위하여 jackson을 사용해보았는데.. 맙소사!!
그동안 삽질을 해왔던거였음...
기존 json 파싱보다 jackson 라이브러리를 사용하는것이 최적인듯...
앞으로 jackson으로 파싱하리~~
자 우선 기존 세팅에서 pom.xml에 dependency를 추가해주도록 하자
<dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> </dependency>
라이브러리추가를 해주었다면 다음은 mvc-config.xml에 jackson을 위한 bean 설정을 해주도록 하자
<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
다음은 흔히들 말하는 vo 클래스 하나를 생성하여 다음과 같이 선언을 해주도록 해보자
public class JSONTest { private int id; private String txt; private ArrayList<String> list; private String[] arr; public String[] getArr() { return arr; } public void setArr(String[] arr) { this.arr = arr; } public ArrayList<String> getList() { return list; } public void setList(ArrayList<String> list) { this.list = list; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTxt() { return txt; } public void setTxt(String txt) { this.txt = txt; } }
VO에 배열과 리스트를 선언해본이유가 json array객체를 어떻게 출력시키는지 궁금해서
둘다 생성해보았음.
마지막으로 @responsebody를 이용한 컨트롤러를 생성하여 vo객체에 데이터들을 담은 후, 브라우저에 컨트롤러 URL을 호출해보도록 하자
. @RequestMapping(value="/jsonTest") public @ResponseBody JSONTest jsonTest() { //가상의 배열및 리스트에 데이터 add ArrayList<String> arraylist = new ArrayList<String>(); arraylist.add("a"); arraylist.add("b"); String[] array = {"a","b","c"}; //VO객체에 SET한후 vo객체자체를 return JSONTest test = new JSONTest(); test.setId(1); test.setTxt("textTxt"); test.setList(arraylist); test.setArr(array); return test; }
실행을 해보도록 하자
※ IE에서는 URL 호출시 JSON 데이터일경우 파일다운로드를 받게끔 되있으므로
크롬에서 컨트롤러 호출을 해보았음
흑흑 ㅠㅠ 잘나온다,.. array / arraylist 상관없이 json array에 알아서 담아서 출력해준다....
코드를 보니 json array가 잘못 출력되는것 확인하였다.
아무래도 그냥 list/array타입의 key/value로 지정이 되야하는데 그냥 문자열만 넣어서 그런가보다.
그래서 다시 list형식의 key/value를 적용하여 간단하게 게시물상세내용 + 다중파일첨부를 가상의 예를 들어서 다시 작성해보았음.
DB통신을 통하여 쿼리 작성을 하려하였으나 그냥 VO에 가상의 데이터를 넣어보기로 하였음
1. VO 클래스를 두개를 작성한다.
- Board.java
public class Board { private int seq; private String title; private String content; private Date regdate; private ArrayList<BoardFile> filelist; public ArrayList<BoardFile> getFilelist() { return filelist; } public void setFilelist(ArrayList<BoardFile> filelist) { this.filelist = filelist; } public int getSeq() { return seq; } public void setSeq(int seq) { this.seq = seq; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public Date getRegdate() { return regdate; } public void setRegdate(Date regdate) { this.regdate = regdate; } }
- BoardFile.java
public class BoardFile { private int fileSeq; private String fileName; private int fileSize; public int getFileSeq() { return fileSeq; } public void setFileSeq(int fileSeq) { this.fileSeq = fileSeq; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public int getFileSize() { return fileSize; } public void setFileSize(int fileSize) { this.fileSize = fileSize; } }
다음은 기존 /jsonTest 컨트롤러내에 set 데이터를 한번 다음과 같이 처리해주도록 하자
@RequestMapping(value="/jsonTest") public @ResponseBody Object jsonTest() { Board board = new Board(); board.setSeq(1); board.setTitle("제목"); board.setContent("내요내용내용"); board.setRegdate(new Date()); ArrayList<BoardFile> filelist = new ArrayList<BoardFile>(); BoardFile boardFile = null; boardFile = new BoardFile(); boardFile.setFileSeq(1); boardFile.setFileName("파일명1"); boardFile.setFileSize(1000); filelist.add(boardFile); boardFile = new BoardFile(); boardFile.setFileSeq(2); boardFile.setFileName("파일명2"); boardFile.setFileSize(25645); filelist.add(boardFile); board.setFilelist(filelist); return board; }
컨트롤러에 대해서 설명을 하자면 게시판의 뷰페이지를 예로 든것이다.
상세보기 클릭시 제목과 내용이나오고, 여러개의 파일목록들에 대한 json 객체를 return!!!
위와같이 작성하고 /jsonTest 를 브라우저에서 호출하게 되면 ...
이번엔 정상적으로 json object 부터 json array까지 정상적으로 잘나오는것을 확인할 수 있었다...
그동안 난 뭘한건지... ㅋ
앞으로 jackson을 사용해주리라~~
도움이 되셨다면 공감클릭! 궁금하신점은 댓글!!
스프링3(Spring3) - 메이븐(maven) pom.xml에서 오라클 JDBC(ojdbc14.jar) 라이브러리 추가하기 (0) | 2014.07.30 |
---|---|
스프링3(Spring3) - RedirectAttributes를 이용하여 리다이렉트 POST 방식으로 데이터 전송하기 (0) | 2014.07.30 |
스프링3(Spring3) - 인터셉터(interceptor) 설정 (4) | 2014.07.28 |
스프링3(Spring3) - SQL 쿼리 출력을 위한 로그레벨 설정 (0) | 2014.07.27 |
스프링3(Spring3) - @PathVariable를 이용하여 parameter를 url형식으로 받기 (0) | 2014.07.26 |
이번 포스팅은 인터셉터에 대한 설정을 작성하려고 한다.
말그대로 spring 의 controller 호출전에 동작하는 방식으로써 보통은 로그인 체크유무가 필요한
곳에서 주로 사용함
예를 들어 게시판의 글쓰기 화면을 이동후, 한참동안 아무런 동작은 안하게 되면 세션이 제거되어 보통 기록해야 할 아이디 또는 이름같은 세션에 들어가있는 정보들이 증발하게된다.
이럴경우 글쓰기를 하게 되면 테이블에는 일반 데이터들은 들어가있거나 혹은 아이디/이름 컬럼을 not null로 생성하였다면 오류발생이 일어날것이다.
가끔 세션이 증발하여 null값이 아닌 공백이 들어갈경우도 있어서 문제가 발생한다.
이럴때는 세션체크를 한 후 세션이 제거된 상태일경우에는 게시물을 등록할 수 없게 해야 한다.
또는 마이페이지의 메뉴 혹은 브라우저에 남아있는 url로 접근을 할 경우에도 세션이 존재하지
않으면 페이지 접근을 막아야 한다.
예전에는 스크립트로 로그인 체크를 하거나 각페이지마다 if문을 주어 로그인 유무를 판단하였다.
반면에 인터셉터설정은 모든페이지에 적용을 해주지 않아도 되며 xml설정과 class 파일 하나 추가로 인하여 해결이 된다.
예를들어보자
가상의 시나리오를 작성해보도록 하자
게시판 글쓰기페이지(/board_write)는 로그인한 사용자만 접근이 가능하다
만약 로그인하지 않은 사용자가 글쓰기페이지 접근할 경우 로그인 페이지(/login)로 이동시킨다
위의 시나리오라 가정한다면
세가지 컨트롤러가 필요할 것이다.
1. 로그인화면 : /login controller
2. 로그인처리 : /findlogin controller
3. 글쓰기 페이지 : /board_write controller
그런다음 인터셉터 클래스 하나를 생성을 해야한다.
위 시나리오대로 진행을 해보도록 하자
1. 로그인화면을 출력할 컨트롤러 + jsp 페이지
실제로 로그인을 구현하거나 글쓰기 폼을 화면에 띄우는건 아님.
@RequestMapping(value="/login") public String login(){ return "login"; }
<!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>Insert title here</title> </head> <body> 로그인 페이지입니다. </body> </html>
2. 글쓰기 페이지 컨트롤러 + jsp 페이지
@RequestMapping(value="/board_write ") public String board_write (){ return "board_write"; }
<!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>Insert title here</title> </head> <body> 글쓰기 페이지 입니다. </body> </html>
3. 세션 생성할 임의의 컨트롤러 해당 컨트롤러는
단순 세션 생성을 위한 것이므로 별도의 jsp 페이지 불필요
@RequestMapping(value="/findlogin") public void findlogin(HttpServletRequest request){ request.getSession().setAttribute("logininfo", true); }
모두 작성 완료 하였으면 이제는 mvc-config.xml 설정부분에 다음과 같이 추가해주도록 하자 위치는 본인 마음대로..
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/board_write"/> <bean class="com.spring.interceptor.InterCeptor"/> </mvc:interceptor> <!-- 추가로 여러개의 인터셉터 설정 가능 <mvc:interceptor> <mvc:mapping path="/admin/board_write"/> <bean class="com.spring.interceptor.AdminInterCeptor"/> </mvc:interceptor> --> </mvc:interceptors>
위의 인터셉터 설정을 확인해보면 /board_write라는 mapping을 받았을경우, 컨트롤러 호출전, InterCeptor 클래스를 먼저 호출한다라고 생각하면 될것임
여러가지의 인터셉터 설정이 가능함
그럼 이제 InterCeptor 클래스를 해당 패키지에 맞추어 생성을 하도록 하자
package com.spring.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; public class InterCeptor extends HandlerInterceptorAdapter{ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){ try { //logininfo 세션값이 널일경우 if(request.getSession().getAttribute("logininfo") == null ){ //로그인페이지로 redirect response.sendRedirect("/login"); return false; } } catch (Exception e) { e.printStackTrace(); } //널이 아니면 정상적으로 컨트롤러 호출 return true; } }
이제 인터셉터 설정이 완료되었다
다음 동작을 실행해보도록 하자
1. 강제로 "/board_write" 컨트롤러 호출 -> "/login" 컨트롤러 페이지로 가는지확인
2. "/findlogin" 컨트롤러 호출 후 "/board_write " 컨트롤러 다시 호출하여 board_write.jsp의 문구가 제대로 보이는지 확인
그럼 실행을 해보도록 하자
1) 세션이 존재하지 않는 상태에서 /board_write 컨트롤러 호출
2) 로그인페이지로 강제 이동
3) 세션생성 컨트롤러 호출
4) 세션이 생성됨(jsp 페이지는 필요없어서 나는 404 오류임)
5) 세션이 생성되었으므로 다시 한번 /board_write 컨트롤러 호출
6) 이번에는 정상적으로 /board_write 컨트롤러 접근 가능
확인결과 인터셉터가 잘 동작하는 것을 확인하였다.
샘플을 토대로 관리자/사용자 세션체크 및 세션이 꼭 필요한 페이지 체크등에 대하여 응용을 하면 될것이다.
도움이 되셨다면 공감클릭! 궁금하신점은 댓글!!
스프링3(Spring3) - RedirectAttributes를 이용하여 리다이렉트 POST 방식으로 데이터 전송하기 (0) | 2014.07.30 |
---|---|
스프링3(Spring3) - @ResponseBody + jackson을 이용하여 심플하게 JSON 구현하기 (0) | 2014.07.30 |
스프링3(Spring3) - SQL 쿼리 출력을 위한 로그레벨 설정 (0) | 2014.07.27 |
스프링3(Spring3) - @PathVariable를 이용하여 parameter를 url형식으로 받기 (0) | 2014.07.26 |
스프링3(Spring3) - 리소스(resource file) 및 favicon.ico 설정 (0) | 2014.07.25 |
이번 포스팅은 spring - mybatis 연동이 된상태로 콘솔창에 sql 쿼리의
parameter 및 result 데이터를 확인하고자 할때 로그레벨을 설정하는 것이다.
기존까지 해온 연동설정에서 추가로 변경만 해주면 된다.
resources 디렉토리내에 logback.xml 이란 파일이 있을텐데 맨 밑으로 내려보면
root 레벨이 info로 되있을텐데 레벨은 info -> debug로 변경해주도록 한 후
쿼리가 뽑히는지 확인하자
그럼 기존 쿼리 테스트를 위해 만들어놓은 컨트롤러 호출을 한후 콘솔에 쿼리 로그가 정상적으로 뽑히는지 확인해보자
위 화면처럼 쿼리로그가 정상적으로 찍히는지 확인하였다.
query = show tables
parameter = 입력값이 없으므로 패스
return data = total : 2
sql 쿼리출력관련은 개발모드에서만 사용하고 상용서버 적용시 로그레벨을 기존 info로 변경하도록 하자
log 설정에 대한 부분은 본인이 제대로 파악하는게 아니므로 시간이 날때 log 레벨 및 설정에 대한 포스팅을 하도록 하겠음.
도움이 되셨다면 공감클릭! 궁금하신점은 댓글!!
스프링3(Spring3) - RedirectAttributes를 이용하여 리다이렉트 POST 방식으로 데이터 전송하기 (0) | 2014.07.30 |
---|---|
스프링3(Spring3) - @ResponseBody + jackson을 이용하여 심플하게 JSON 구현하기 (0) | 2014.07.30 |
스프링3(Spring3) - 인터셉터(interceptor) 설정 (4) | 2014.07.28 |
스프링3(Spring3) - @PathVariable를 이용하여 parameter를 url형식으로 받기 (0) | 2014.07.26 |
스프링3(Spring3) - 리소스(resource file) 및 favicon.ico 설정 (0) | 2014.07.25 |
spring 3 이후부터 지원이 되는 기능이다.
본인이 주로 쓰는 경우에는 특정 parameter값을 페이지 전환하면서 유지를 해야 할 경우이다.
예를들어
상단 메뉴를 누르고 메뉴의 focus를 유지하고자 할경우 보통
http://URL?gnb=board
형식으로 주면서 특정 메뉴의 모든 페이지에 gnb=board라는 값이 따라붙게 된다.
위와같은 url을 PathVariable 어노테이션을 사용하게 된다면
http://URL/board
와 같은 식으로 변경이 가능하다
물론 URL 뒤에만 붙이는건 아니고 URL 중간에 접목도 가능하다.
예를 들도록 해보자
1) 일반 GET방식으로 서버에서 값 확인하기
* JAVA 샘플코드
@RequestMapping("/test") public void test(HttpServletRequest request){ System.out.println("================"); System.out.println("get방식 parameter 값:"+request.getParameter("menu")); System.out.println("================"); }
* 호출화면 + 콘솔값
2) @PathVariable 이용하여 서버에서 값 확인하기
* JAVA 샘플코드
@RequestMapping("/test/{menu}") public void test(@PathVariable String menu){ System.out.println("================"); System.out.println("get방식 parameter 값:"+menu); System.out.println("================"); }
* 호출화면 + 콘솔값
결과는 동일...
어떤가 PathVariable 어노테이션을 적용한게 좀 더 깔끔해 보이지 않는가~~
결과값은 똑같고 PathVariable 는 하나 그이상도 가능하다.
다만 주의할점은 null이나 공백값이 들어가는 parameter라면 적용하지 말도록 하자
인식을 못하니... ㅎㅎㅎ
도움이 되셨다면 공감클릭! 궁금하신점은 댓글!!
스프링3(Spring3) - RedirectAttributes를 이용하여 리다이렉트 POST 방식으로 데이터 전송하기 (0) | 2014.07.30 |
---|---|
스프링3(Spring3) - @ResponseBody + jackson을 이용하여 심플하게 JSON 구현하기 (0) | 2014.07.30 |
스프링3(Spring3) - 인터셉터(interceptor) 설정 (4) | 2014.07.28 |
스프링3(Spring3) - SQL 쿼리 출력을 위한 로그레벨 설정 (0) | 2014.07.27 |
스프링3(Spring3) - 리소스(resource file) 및 favicon.ico 설정 (0) | 2014.07.25 |