먼저 설정해주어야하는것부터 시작한다.
[pom.xml]
1 2 3 4 5 6 | <!-- https://mvnrepository.com/artifact/net.sf.json-lib/json-lib-ext-spring --> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib-ext-spring</artifactId> <version>1.0.2</version> </dependency> | cs |
'JSONObject'를 사용할 수 있게 해주는 소스.
Maven Repository 사이트에서 artifactId로 검색하면 상위에 뜬다.
[dispatcher-servlet.xml]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <context:annotation-config /> <context:component-scan base-package="spring.controller,spring.service,spring.common, spring.interceptor,ajax.controller" /> <!-- ajax.controller를 bean객체로 만들기 위해 scan에 추가한다. --> <mvc:annotation-driven> <mvc:message-converters> <!-- @ResponseBody로 String 처리할때 한글처리하기위한 bean --> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp" /> </bean> <!-- property들을 앞에 붙히고 뒤에붙혀서 뷰 경로를 만들어준다 --> </beans> | cs |
[mybatis.xml]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <!-- 프로퍼티 파일로부터 데이터를 읽어온다. --> <context:property-placeholder location="classpath:db.properties" /> <!-- 커넥션 풀을 만들기위한 과정. db.properties에 있는 값을 가져와 EL로 꺼냄 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.driver}" /> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" > <list> <value>classpath*:sql/*.xml</value> <value>classpath*:mybatis/*.xml</value> </list> <!-- 여러경로의 맵퍼파일을 추가하고싶다면 list태그안에 value태그로 선언해준다. --> </property> <!-- ampperLocations에는 맵퍼파일의 경로를 잡는다 value에 와일드카드를써서 여러개의 파일을 한번에 지정할 수 있다. --> </bean> <bean id="cityDAO" class="ajax.controller.CityDAO"> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean> <!-- bean객체로 올릴 DAO 클래스 선언. CityDAO 타입을 받아서 쓸수있는 Autowired속성 추가하는것을 잊지말자. --> | cs |
이부분에서 중요한건, classpath는 resources 밑에서부터 받아오는 파일 경로를 의미하고,
여러 경로에 있는 mapper파일을 추가하고싶다면, 위와같은 방법으로도 사용할 수 있다.
또한, DB연결해서 받아올 DAO클래스를 type에 맞춰서 bean 컨테이너에 올려놓은것과 연결하기위해
@Autowired속성 사용하는것도 잊지말자.
[city.jsp]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <%@ page contentType="text/html; charset=UTF-8"%> <%@ page trimDirectiveWhitespaces="true" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <% String cp = request.getContextPath();// /springMvc request.setCharacterEncoding("UTF-8"); %> <!DOCTYPE html> <html> <head> <title>Insert title here</title> <script src="https://code.jquery.com/jquery-3.1.0.min.js"></script> </head> <body> <select id="sido" onchange="cityList()"> <option value = "" >::시도선택::</option> </select> <select id="city"> <option value="">::도시선택::</option> </select> <input type="button" value=" 확인 " onclick="result()"> </body> </html> | cs |
[script 부분]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | <script> $(function(){ //body로딩이 다 된후에 바로 실행되는 레디펑션 로직. //시도테이블의 list가져오기위한 로직. var url = "<%=cp%>/city/sidoList.do"; // /프로젝트명/city/sidoList.do 를 받아오는 url. // 프로젝트명은 맨위에 스크립트릿으로 받아옴. var params = "dumi="+new Date(); //dumi=Mon Sep 17 2018 17:15:07 GMT+0900 (한국 표준시) 형식으로뜬다. //실행한 그때의 현재시간으로. console.log("params : " , params); $.ajax({ 'type' : "post", 'url' : url, // ==> /프로젝트명/city/sidoList.do에서 // ==> /프로젝트명제거 + 확장자 .do 제거되고 실행되면서 Controller로 요청후 이동. 'data' : params, dataType : "json", success : function(args){ //성공하면 args라는 변수에 담겨오는데 //파고드는게 불편하다면 var result = args.data; 로 선언하고 result.length로 꺼내도 가능하다. console.log("성공한 데이터 : " , args) for(var i=0; i < args.data.length; i++){ $("#sido").append("<option value='"+args.data[i]+"'>"+args.data[i]+"</option>"); //id가 sido인 요소선택 //append로 기존 셀렉터로 선택된 요소 다음에 다음내용이 들어감 //<option value='0'>서울</option> 이런식으로 sido의 요소안에 자식으로 들어감 // args.data[i] : args 는 function(args)의 인자. //data는 controller.java에서 json객체에 넣어준 key(여기서는 list가 값이 된다). //[i]는 list의 몇번쨰 데이터를 가져올지 배열을 나타냄 } }, error : function(err){ alert("첫번째 ajax로직 : " , err.responseText); } }); }); function cityList(){ var snum = $("#sido").val(); if(snum==''){ $("#city option").each(function(){ $("#city option:eq(1)").remove(); // city option의 1번째를 계속 삭제(0번째만 남기고 모두 지우게 된다) , // eq : 지정된 index 번째의 엘리먼트 선택 }); //$("#city").append("<option value=''>::도시선택::</option>"); // 위의 반복문으로 모두 삭제되어 있으므로 추가해준다. // 위의 명령문은 바로 위의 엘리먼트가 1이아닌 0이었을 때 사용하면 됨. return; } var url = "<%=cp%>/city/cityList.do"; var params = "snum="+snum+"&dumi="+new Date(); $.ajax({ 'type' : "post", 'url' : url, 'data' : params, 'dataType' : 'json', success : function(args){ $("#city option").each(function(){ $("#city option:eq(0)").remove(); }); $("#city").append("<option value = ''>::도시선택::</option>"); for(var i=0; i<args.data1.length; i++){ var area2 = args.data1[i]; $("#city").append("<option value='"+area2['AREA2']+"'>"+area2['AREA2']+"</option>"); //$("#city").append("<option value='"+args.data1[i]['AREA2']+"'>"+args.data1[i]['AREA2']+"</option>"); //이런 형태도 가능 } }, error : function(err){ alert("두번째 ajax 로직 : ", err.responseText); } }); } //확인 버튼을 누르면 실행될 로직. function result(){ var sido = $("#sido :selected").text(); var city = $("#city :selected").text(); //선택자를 찾아가서, 선택된 옵션의 text를 뽑아오는 변수들. var s = sido + " " + city; alert("sido + city 출력 : " + s); } </script> | cs |
[CityController.java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | @Controller public class CityController { @Autowired private CityService service; public void setService(CityService service) { this.service = service; } @RequestMapping(value = "/city/city.do") public String city() throws Exception { return "ajax/city"; } @RequestMapping(value="/city/sidoList.do" , method = RequestMethod.POST) public void sidoList(HttpServletResponse response) throws Exception { List<String> list = service.listSido(); //service.listSido()는 CityService를 구현한 CityServiceImpl에 있는 메서드를 실행한다. //그 메서드에서 데이터베이스에서 selectList로 가져온 list를 저장하는 로직을 사용한 후 list 저장하고 리턴. JSONObject jsonObject = new JSONObject(); jsonObject.put("data", list); //그 데이터를 담은 list를 key값 'data'라는 이름으로 list를 담음. //이것이 가능한 이유는 JSON객체는 {String, Object} 타입으로 받을 수 있기 때문이다. response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); out.print(jsonObject.toString()); } //produces 부분은 잘 안먹을때도 있어서 xml에서 설정하는게 좋다고 함. @RequestMapping(value = "/city/cityList.do" , method = RequestMethod.POST,produces="text/plain;charset=UTF-8") @ResponseBody public String cityList(HttpServletResponse response, @RequestParam("snum") String city) throws Exception { response.setContentType("text/html; charset=UTF-8"); List<Map<String,Object>> list = service.listCity(city); System.out.println("cityList메서드에있는 Map으로 받은 List 내용 : " + list); JSONObject jsonObject = new JSONObject(); jsonObject.put("data1", list); return jsonObject.toString(); //위의 sidoList메서드는 데이터를 담아서 값을 던져주고 끝내는것이기때문에 void 메서드로 사용하는 1회성이고. //이 cityList메서드는 데이터를 담은 값을 다시 responseBody로 보내기위해 return 타입을 String으로 받아온다. } } | cs |
실제로 .listSido() 와, .listCity(city) 가 실행되는 클래스
[CityServiceImple.java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | package ajax.controller; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class CityServiceImpl implements CityService{ @Autowired private CityDAO cityDAO; public void setCityDAO(CityDAO cityDAO) { this.cityDAO = cityDAO; } public List<String> listSido(){ List<String> list = null; try { list = cityDAO.getListData("city.listSido"); }catch(Exception e) { System.out.println("String으로 받아온 메서드 : " +e.toString()); } return list; } public List<Map<String,Object>> listCity(String city){ List<Map<String,Object>> list = null; try { list = cityDAO.getListData("city.listCity", city); } catch (Exception e) { System.out.println("Map으로 받아온 메서드 : "+ e.toString()); } return list; } } | cs |
getListData 사용되는 클래스
[CityDAO.java]
1 2 3 4 5 6 7 8 9 10 11 12 | public class CityDAO extends SqlSessionDaoSupport{ public List<String> getListData(String string){ List<String> sido = getSqlSession().selectList(string); return sido; } public List<Map<String,Object>> getListData(String string, String city){ List<Map<String,Object>> selectCity = getSqlSession().selectList(string, city); return selectCity; } } | cs |
getSqlSession()이 맨 처음 mybatis.xml에서 지정한 sql/*.xml에 있는 mapper파일을 읽어들여서
그 안에 선언한 select를 실행해서 데이터를 담아서 List에 저장한다.
그 mapper파일은 밑에와 같다.
[cityMapper.xml]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?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="city"> <select id="listSido" resultType="String"> select distinct area1 from zipcode order by area1 asc </select> <select id="listCity" parameterType="String" resultType="Map"> select distinct area2 from zipcode where area1 = #{area1} order by area2 asc </select> </mapper> | cs |
'JAVA > Spring' 카테고리의 다른 글
Spring MVC - 두번째 LoginController (0) | 2018.09.19 |
---|---|
String MVC - 뷰(ViewResolver) 원칙 (0) | 2018.09.19 |
Spring MVC - BindingResult 사용법 (0) | 2018.09.13 |
Spring - RESTful 예제 (2) | 2018.09.13 |
@ModelAttribute 추가 공부내용. (0) | 2018.09.12 |