jquery ajax json mvc 스프링 post 

jquery 로 스프링 통신시 컨트롤로 선언 방법과 리턴방법 jquery에서 사용법등을 정리해보겠습니다. 

일단 스프링 에서 컨트롤러 선언입니다. 저는 사과로 선언을 해보겠습니다. 

@RequestMapping(value = "/apple", method = RequestMethod.POST, consumes = "application/json")
	public @ResponseBody CommonData apple(@RequestBody CommonData dto) {
		CommonData result_data = new CommonData();
		String apple = dto.get("apple","");
		result_data.put("result",apple);
		return result_data;
	}

@RequestBody 해쉬맵 변수명 으로 하면 강종항목들이 키와 값으로 분리되어  들어갑니다. 

CommonData 를 궁금해 하시는분들이 많으셔서 해쉬맵인데 전자정부프레임워크 처럼 map데이터사용시 쓸려고 재정의 해 놓은것 뿐입니다. 

public class CommonData extends LinkedHashMap {
	public void put(String key, Object value){
		super.put(key, value);
	}

	public String get(String key) {
		if(super.get(key)!=null)
		{
			return super.get(key).toString();
		}
		else
		{
			return null;
		}		
	}
	public String get(String key,String value)
	{
		if(super.get(key)!=null)
		{
			return super.get(key).toString();
		}
		else
		{
			return value;
		}	
	}
	public Object getObj(String key) {
		return super.get(key);
	}
}

거기에 @ResponseBody 해주면 해쉬맵이 json형태로 변화되어 응답합니다. 안에 리스트데이터나 뭐 각종데이터를 넣어서 보내어도 계층화되어 전송이 됩니다. 

ajax소스인데요. 

		$.ajax({
            url : '${pageContext.request.contextPath}/jqueryajax/apple',
            type : 'post',
            contentType: 'application/json',
            data : JSON.stringify ({'apple':'100','banana':200}),
            dataType : 'json',
            success : function(data){
                // 통신 성공시 실행....
            	data = data.RESULT;
            },
            error : function(xhr,status,error){
                // 통신 실패시 실행....
                // alert(xhr.status + " " + xhr.statusText);
                // alert("통신실패 : ["+xhr.status + " " + xhr.statusText+"]");
                alert("데이터 불러오는데 실패했습니다.");
            },
            complete : function(data){
                // 통신 실패했어도 최종 완료시 실행...
                // alert('complete');
            }
        });

이런식으로 호출해서 사용하시면 됩니다. 

 

'JQUERY' 카테고리의 다른 글

jqgrid jquery 내부값 변경하기 특정셀값 jqgrid  (0) 2014.12.01
JUQERY 폰 전화 PHONE 정규식 검사 - 포함  (0) 2014.12.01
jquery정리  (0) 2014.11.20
블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,

spring mvc homepage 스프링 홈페이지 만들기 6

이번에는 로그인을 해볼예정이에요. id와 패스워드가 필요할텐데요. 전 아까 sunplan 이라고 id를 만들었어요. 패스워드는 쉽게 121212로 하였네요. 이걸 가지고 로그인 하는걸 만들어 볼께요. 

TOP.JSP파일을 수정할꺼에요. 

 <!-- Right navbar links -->
      <ul class="order-1 order-md-3 navbar-nav navbar-no-expand ml-auto">
      <c:if test="${not empty login}">			
      	<li class="nav-item">
      		<button type="button" class="btn btn-outline-primary nav-link"  onclick="goLogout()">${login.uname}님</button>&nbsp;
      	</li>
	  </c:if>
	  <c:if test="${empty login}">
	  	<li class="nav-item">
      		<input type="text" class="form-control" placeholder="아이디" id="uid">&nbsp;
      	</li>
      	<li class="nav-item">
      		<input type="password" class="form-control" placeholder="패스워드" id="upassword">&nbsp;
      	</li>
      	<li class="nav-item">
          <button type="button" class="btn btn-outline-primary" onclick="goLogin()">로그인</button>&nbsp;
        </li>	  
      	<li class="nav-item">
          <a class="nav-link" href="/user/register">가입하기</a>
        </li>
      </c:if>
        <!-- Messages Dropdown Menu -->
        <li class="nav-item dropdown">
        </li>
        <!-- Notifications Dropdown Menu -->
        <li class="nav-item dropdown">
        </li>
        <li class="nav-item">
          <a class="nav-link" data-widget="control-sidebar" data-slide="true" href="#" role="button"><i
              class="fas fa-th-large"></i></a>
        </li>
      </ul>
    </div>
  </nav>
  <!-- /.navbar -->


  
<script>
function goLogout()
{	
	var url;
	url = '/user/logout';	
	var data = JSON.stringify({
	});
	getPostData(url,data,callback_common,false);
}
function goLogin()
{	
	var url;
	url = '/user/login';
	
	
	var data = JSON.stringify({
		uid : $("#uid").val()
		 , upw : $("#upassword").val()
	});
	getPostData(url,data,callback_common,false);
}
var callback_common = function (result)
{
	if(result['result']=='LOGIN_SUCCESS')
	{
		showmessage("알림","로그인 되었습니다..",5000,'');
		self.location = "${pageContext.request.contextPath}/";
	}
	if(result['result']=='LOGOUT_SUCCESS')
	{
		showmessage("알림","로그아웃 되었습니다..",5000,'');
		self.location = "${pageContext.request.contextPath}/";
	}
	else if(result['result']=='ID_NOT_FIND')
	{	
		showmessage("알림","아디를 확인해주세요.",5000,'');
		$("#uid").val("");
		$("#uid").focus();
	}
	else if(result['result']=='PASSWORD_FAIL')
	{	
		showmessage("알림","아디를 확인해주세요.",5000,'');
		$("#uid").val("");
		$("#uid").focus();
	}
	else
	{
		showmessage("알림",result['message'],20000,'');
		ms_alert("알림","내용이 등록/수정을 실패하였습니다");
	}
}
</script>

 <!-- Right navbar links --> 아래쪽에 로그인이 가능한 폼을 추가했어요. 

login 값의 유무에 따라 로그인 로그아웃 기능을 넣었어요. 

top.jsp
0.01MB

컨트롤러는 이렇게 추가했어요. 

	@ResponseBody
	public CommonData logout(HttpServletRequest request, HttpServletResponse response, @RequestBody CommonData dto, Model model) throws Exception{
		Map<String, String> paramMap = new HashMap<>();
		CommonData result = new CommonData();
		HttpSession session = request.getSession();
		Util_Message smsp = Util_Message.getInstance();
	   Object obj = session.getAttribute("login");
	   if (obj != null) {
		Member vo = (Member) obj;
		String ip = request.getRemoteAddr();
		dto.put("u_idx", vo.getIdx());
		dto.put("uip", ip);
		dto.put("ustate", "logout");
		service.insert(dto, "User_Mapper.user_login_history");
		System.out.println("logout.................................2");
		session.removeAttribute("login");
		session.invalidate();

		System.out.println("logout.................................3");
		Cookie loginCookie = WebUtils.getCookie(request, "loginCookie");

		if (loginCookie != null) {
			loginCookie.setPath("/"); loginCookie.setMaxAge(0);
			response.addCookie(loginCookie); 
			}
			
		}
	   result.put("result", "LOGOUT_SUCCESS");
	    return result;
	}
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	@ResponseBody
	public CommonData post_login(HttpServletRequest request, HttpServletResponse response, @RequestBody CommonData dto, Model model) throws Exception{
		Map<String, String> paramMap = new HashMap<>();
		CommonData result = new CommonData();
		HttpSession session = request.getSession();
		Util_Message smsp = Util_Message.getInstance();
	    if (session.getAttribute("login") != null) {
	      smsp.print_String("clear login data before");
	      session.removeAttribute("login"); //로그인 정보 삭제
	    }	    
	    smsp.print_CommonData(dto); //넘어온데이터 출력.
	    
	    String useCookie=dto.get("useCookie");
	    
		int cnt = service.listSearchCount(dto, "User_Mapper.user_id_check");
		if (cnt == 0)
		{
			result.put("result", "ID_NOT_FIND");
			result.put("message", "ID가 없습니다.");
			return result;
		}
		Member vo = service.select_member(dto, "User_Mapper.tb_member_select_one");
		if(vo==null)
		{
			result.put("result", "PASSWORD_FAIL");
			result.put("message", "패스워드를 확인해주세요.");
			return result;
		}
		String ip = request.getRemoteAddr();
		dto.put("u_idx", vo.getIdx());
		dto.put("uip", ip);
		dto.put("ustate", "login");
		service.insert(dto, "User_Mapper.user_login_history");
		smsp.print_String_no_line("로그인정보가 있습니다.");
		String CPath = "/";
		//SecurityMember s_mem = new SecurityMember(vo);
		model.addAttribute("userVO", vo);
		session.setAttribute("login", vo);
		if(useCookie!=null)
		{	
			if(useCookie.equals("true"))
			{
				smsp.print_String_no_line("쿠키정보를 추가합니다.");
				//쿠키...
			    //로그인 유지기간 섹션값저장
				int limit_time = 60*60*24*365;//1년일
				Date sessionLimit = new Date(System.currentTimeMillis()+(1000*limit_time));
				dto.put("sessionId",session.getId());
				dto.put("sessionLimit",sessionLimit);
				service.update(dto, "User_Mapper.keepLogin");
				Cookie loginCookie = new Cookie("loginCookie", session.getId());
				loginCookie.setPath("/");
				loginCookie.setMaxAge(limit_time);
				smsp.print_String("CPath : " + CPath);
				CPath = "/";			
				response.addCookie(loginCookie);
			}
		}
		result.put("result", "LOGIN_SUCCESS");
		return result;
	}

로그인 로그아웃 부분을 추가했어요. 

User_Controller.java
0.01MB

mapper파일도 수정을 해줘요. 

 <select id="tb_member_select_one" resultType="com.eunhocompany.domain.Member"> 
        SELECT tm1.idx
		     , tm1.uid
		     , tm1.uname
		     , tm1.uchart
		     , tm1.uemail
		     , tm1.umobile
		     , tm1.menu_lv
		     , tm1.join_pass
		     , tm1.mt_use
		FROM tb_member tm1
         where tm1.mt_use = 'Y'
           and tm1.uid = #{uid}
           and tm1.upw = #{upw}
         order by menu_lv desc
		 limit 1
    </select>
    
     <insert id="user_login_history">		
		insert into tb_login_history(
					u_idx
				  , uip
				  , ustate
				  , mt_input_wdate
				  )
		   values(  #{u_idx}
				  , #{uip}
				  , #{ustate}
				  , now()
		          )
	</insert>

 

User_Mapper.xml
0.00MB

로그인 로그아웃 을 해볼께요. 

로그인 로그아웃

로그인 로그아웃을 확인해봤어요. 

히스토리도 잘 남는지 볼께요. 

로그인 기록

다음은 게시판을 만들어볼께요. 

블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,

spring mvc homepage 스프링 홈페이지 만들기 3

mysql을 설치해주세요. 헐.. 전 mariadb를 설치되어 있네요. 

mariadb10.4

음 mariadb로 설치할께요 mysql과 동일하게 접속이 되니 그냥 진행할께요. 

db를 하나 만들어요. home_page로 만들었어요. 
schemas 잘만들어지네요.

mysql workbench 프로그램으로 생성이 되니 mysql홈페이지에서 다운받아 설치하시면되요. 

SELECT HOST, USER, PASSWORD FROM USER;

CREATE USER 'eunhopapa'@'%' IDENTIFIED BY 'eunho20190000';
SELECT HOST, USER, PASSWORD FROM USER;

db를 생성해요. mariadb도 버전이 오르면서 툴에서 생성하는게 잘 안되어서 명령어로 생성해요. 

권한등을 설정할꺼에요. 
dba설정

전 모든권한을 주었어요.

이렇게 db생성이 되었습니다. 

그리고나서 toad for mysql 설치합니다. 

접속 설정

이렇게 해서 db에 접속을 해요. 잘되네요. 이제 스프링에 세팅해줄께요. 

/homepage/src/main/webapp/WEB-INF/spring/root-context.xml
/homepage/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml

두파일을 수정해요.

엑셀다운로드 mybitis log 인터셉터등으로 다양한 파일을 생성해야해요. 내용은 없고 추가해주도록할게요.

interceptor를 추가해줄께요. 하나는 로그인 관련 처리할것이고 하나는 메타태그 관련정보를 다를거에요. 

AuthInterceptor.java
0.00MB
MetaInterceptor.java
0.00MB

src->main->resources 안에 아래의 파일을 추가수정해요. 

log4j.xml
0.00MB
log4jdbc.log4j2.properties
0.00MB
mybatis-config.xml
0.00MB

그리고 쿼리 관련 xml도 만들어줘요. 

BasicMapper.xml
0.00MB

WIN-INF 에다가 views.xml 파일을 복사해줘요. 

views.xml
0.00MB

그럼 실행을 해보면 별로 변한건 없이 db연결만 되었어요. 테스트는 따로 안할께요. 

그리고 jsp 파일에 <div class="container"> 부분을 모두 <div class="container-fluid"> 이렇게 변경을 해주세요

전 화면에 꽉찬 페이지를 만들고 싶어서 그래요. 

홈페이지

꽉 찬 페이지가 나오는것을 확인할수 있어요. <div class="col-lg-6"> 을 <div class="col-lg-12"> 변경해야하는것도 잊지 마세요.

블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,

spring  mvc homepage  스프링 홈페이지 만들기 2

adminlte를 붙여볼게요. 

여기에 복사

경로는 src -> main -> webapp -> resources 에 압축을 푼 adminlte를 복사를 해요. 

※AdminLTE-3.0.4 가 길어보여서 AdminLTE로 이름 변경했어요. 

샘플소스

복사를 모두 해도 되겠지만 일단 조금씩 해볼께요. 용량이 큰지라 top-nav.html 기준으로 가져와 볼게요.

top-nav.html 파일을 메모장에서 열어요. 대충 보니까 두 군데 파일이 필요해 보이는데 2 폴더 용량이 61메가나 되네요.

모든 소스가 다 포함되어 있어서 사용하는 파일만 하나하나 복사할까 했지만 그냥 다 복사할게요.

그리고 home.jsp파일내용을 top-nav.html내용으로 수정해줍니다. 경로도 수정야 하는데요. 첨부파일을 참고해주세요.

home.jsp
0.01MB

실행하여 결과를 보면요. 

home.jsp수정후 결과

결과를 잘 보았는데요. 이제 이걸 쪼갤 예정입니다. 위쪽 메뉴 부분과 아래쪽 부분은 다른 페이지에서 공통으로 사용하는 영역이고요. 

본문 내용만 계속 수정이 이루어질 예정이기 때문에 그래요.

페이지 소스를 보니 보니 <!-- Content Wrapper. Contains page content --> 부분 위쪽과 <!-- /.content-wrapper --> 부분 아래쪽으로 나누면 될 거 같아요. 

views안에 하위 폴더를 만들어요 저는 include라는 폴더를 만들었어요. 

그리곤 home.jsp파일을 복사를 했어요. 

파일명은 top과 bottom이라고 지었어요 주석을 보니 헤더와 풋터로 해야 할 것 같은 느낌인데 그냥 진행할게요. 

top bottom.

top는 <!-- Content Wrapper. Contains page content --> 위쪽만 남기고 bottom은 <!-- /.content-wrapper -->아래쪽만남겨요.

home.jsp 파일내용도 수정을 해요. 

<!-- Content Wrapper. Contains page content --> 와  <!-- /.content-wrapper --> 사이내용만 남기고 위아래를 지워요. 

그리고 위아래로 두파일을 포함시켜요. 

<%@include file="include/top.jsp"%>
<%@include file="include/bottom.jsp"%>

그럼 이렇게 파일3개가 수정되었어요. 첨부한 파일을 참고하세요. 

home.jsp
0.00MB
top.jsp
0.01MB
bottom.jsp
0.00MB

그리고 결과를 확인해보면 이렇게 나와요. 

아까와 결과가 같지요? 

이제 로그인이라던지 가입하기 같은 걸 해볼 거예요. db를 설치하고 해야 할 텐데 

전 mysql을 사용할 예정이에요. 버전은 상관없어요. 

참고자료 book.naver.com/bookdb/book_detail.nhn?bid=9425458

 

코드로 배우는 스프링 웹 프로젝트

[코드로 배우는 스프링 웹 프로젝트]는 개발 현장에서 사용하는 도구로서 스프링을 취급하는 책으로, SPRING FRAMEWORK(이하 스프링)를 이용해서 ‘웹 프로젝트’를 어떻게 진행하는지를 설명한다. �

book.naver.com

참고 카페 cafe.naver.com/gugucoding

 

구멍가게코딩단 : 네이버 카페

안녕하세요? 구멍가게 코딩단의 활동을 위한 카페입니다.

cafe.naver.com

 

블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,

spring  mvc homepage  스프링 홈페이지 만들기 1

스프링을 이용하여 홈페이지를 제작해볼 예정입니다. 

최대한 간단하게 필요한 결과 위주로 구성해볼 예정입니다.

UI는 https://adminlte.io/themes/v3/pages/layout/top-nav.html를 이용할 예정입니다.

소스코드를 다운로드 받아주세요.
용량

압축을 해제하니 용량이 제법 많으네요. 일단 다운로드한 후 잘 보관해 놓으세요.

STS를 설치해주세요. 그리고 새로운 프로젝트를 시작해요.

스프링프로젝트생성

프로젝트를 생성을 해요. 생성할때 Spring MVC Project로 해주세요. 

서버를 실행해보세요. 톰캣서버로 실행을 할 거예요. 8 버전으로 맞추어 주세요. 

실행을 하면 이런 화면이 보일꺼에요. 

hello world

??? 표도 나오고 그러죠? 이제 utf8환경으로 세팅을 할 건데요. 세팅되어 있는 환경을 복사하는 형태로 진행할게요.

안에 내용은 따로 공부해보세요. 검색하면 잘 나와요. 

처음에 할 일은 pom.xml을 수정할 거예요. 

pom.xml

이 부분을 남기고 모두 첨부한 pom.xml과 같게 수정을 해줘요 안에 필요 없는 내용은 삭제하시면 돼요. 

pom.xml
0.01MB

다음은 web.xml을 수정할게요. 

web.xml
0.00MB

web.xml내용을 복사해주세요.

이제 jsp페이지를 수정할 거예요. 

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
	<title>Home</title>
</head>
<body>
<h1>
	Hello world!  
</h1>

<P>  The time on the server is ${serverTime}. </P>
</body>
</html>

 

내용일 텐데요 아래와 같이 수정을 해요. 

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<html>
<head>
	<title>Home</title>
</head>
<body>
<h1>
	Hello world!  
</h1>

<P>  The time on the server is ${serverTime}. </P>
</body>
</html>

 

서버 폴더 안에 톰캣 8이 있어요 거기에 server.xml이 있는데 이걸 수정할 거예요.

<Context docBase="homepage" path="/" reloadable="true" source="org.eclipse.jst.jee.server:homepage"/></Host>

path를 지우세요. 이러면 localhost:8080으로 접속 시 바로 home.jsp내용이 나와요. 

헬로우 월드가 출력되었죠?

다음은 ADMINLTE3 네이게이션페이지를 출력해볼께요. 

 

참고자료

https://book.naver.com/bookdb/book_detail.nhn?bid=9425458

 

코드로 배우는 스프링 웹 프로젝트

[코드로 배우는 스프링 웹 프로젝트]는 개발 현장에서 사용하는 도구로서 스프링을 취급하는 책으로, SPRING FRAMEWORK(이하 스프링)를 이용해서 ‘웹 프로젝트’를 어떻게 진행하는지를 설명한다. �

book.naver.com

참고카페

https://cafe.naver.com/gugucoding

 

구멍가게코딩단 : 네이버 카페

안녕하세요? 구멍가게 코딩단의 활동을 위한 카페입니다.

cafe.naver.com

 

블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,

spring mvc 스프링 바코드 생성 하기 Zxing 사용법

안녕하세요. spring 프로젝트중 바코드를 생성해서 회원에게 날려줘야 할일이 생겼어요. 

그래서 지금 바코드 생성 관련해서 찾아보니 zxing를 사용한 방법이 공개되어 있었어요. 

일단 메이븐에서 라이브러리 다운로드를 위해 설정을 합니다. 

		<!-- https://mvnrepository.com/artifact/com.google.zxing/core -->
		<!-- 구글바코드 오픈소스 -->
		<dependency>
		    <groupId>com.google.zxing</groupId>
		    <artifactId>core</artifactId>
		    <version>3.4.0</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.google.zxing/javase -->
		<dependency>
		    <groupId>com.google.zxing</groupId>
		    <artifactId>javase</artifactId>
		    <version>3.4.0</version>
		</dependency>

그리고나서 컨트롤러 위치한 곳에 바코드 이미지를 받아가는 코딩을 합니다. 

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;

라이브러리를 import를 하고요. 

@RequestMapping(value = "/get_barcode", method = RequestMethod.GET)
	public ResponseEntity<byte[]> get_partner_image(HttpServletRequest request, Model model) throws Exception {
		 smsp.print_String("get_barcode ==>" + "아악."  );
		String text ="https://digital365365.com";
        String _formatName = text;
        text = new String(text.getBytes("UTF-8"), "ISO-8859-1");
      
 		byte[] imageInByte_re = smsp.getBarCodeImage(text, 840, 160);
 		//smsp.print_String(image.toString());
 		HttpHeaders headers = new HttpHeaders(); 
 		String mt_filename = text+".png";
        String formatName = "png";	      
	      MediaType mType = MediaUtils.getMediaType(formatName);
	      //smsp.print_String(mType.toString());
	      if(mType != null){
		        headers.setContentType(mType);
		      }else{
		    	mt_filename = new String(mt_filename.getBytes("UTF-8"), "ISO-8859-1");
		        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		        headers.add("Content-Disposition", "attachment;filename=\""+mt_filename+"\";");
		        headers.add("Content-Transfer-Encoding", "binary");
		      }
       
	      return new ResponseEntity<byte[]>(imageInByte_re, headers,HttpStatus.OK);
	}

바코드 생성코드는 이렇게 있습니다. 

public static byte[] getBarCodeImage(String text, int width, int height) {
		try {
			Hashtable<EncodeHintType, ErrorCorrectionLevel> hintMap = new Hashtable<>();
			hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
			Writer writer = new Code128Writer();
			BitMatrix bitMatrix = writer.encode(text, BarcodeFormat.CODE_128, width, height);
			ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
			MatrixToImageWriter.writeToStream(bitMatrix, "png", byteArrayOutputStream);
			return byteArrayOutputStream.toByteArray();
		} catch (Exception e) {
			return null;
		}
	}

이상 정리해보았습니다. 

<img src="${pageContext.request.contextPath}/cp_a/get_barcode" alt="바코드">

 

블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,

Spring java excel download 스프링 엑셀 다운 poi

SRPING MVC 이미지

안녕하세요. 웹 개발일을 하다 보면 엑셀 파일을 요청받을 일들이 있어요. 

SPRING에서는 아파치 소프트웨어 재단에서 만든 POI를 사용할 수 있어요. 

마이크로소프트 오피스 파일들을 읽고 쓰는 기능을 제공하는데요. 워드, 엑셀, 파워포인트 파일을 지원하고 있어요. 최근 OFFICE OPEN XML FILE FORMATS(*. DOCX,*. XLSX,*. PPTX)등 지원 파일을 늘려가고 있다고 해요. 

처음 메이븐 설정을 해요. 

		<!-- 엑셀파일 -->
		<dependency>
		    <groupId>org.apache.poi</groupId>
		    <artifactId>poi</artifactId>
		    <version>3.13</version>
		</dependency>
		<dependency>
		    <groupId>org.apache.poi</groupId>
		    <artifactId>poi-ooxml</artifactId>
		    <version>3.13</version>
		</dependency>
		<dependency>
		    <groupId>org.apache.commons</groupId>
		    <artifactId>commons-collections4</artifactId>
		    <version>4.0</version>
		</dependency>

SERVLET-CONTEXT.XML 파일 내용을 찾아보면 InternalResourceViewResolver가 선언되어 있을거에요. 

<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>

JSP페이지로 이름을 매핑해주는것인데 대부분 설정이 되어 있을 거예요.

저희가 받아야 할 건 JSP페이지가 아니에요. 

XmlViewResolver를 설정해줘야 해요. 조금 귀찮긴 한데 한번 만들어 놓으면 다른 프로젝트에도 복사해서 사용하면 돼요.

<beans:bean id="viewResolver1" class="org.springframework.web.servlet.view.XmlViewResolver">
        <beans:property name="order" value="1"/>
        <beans:property name="location" value="/WEB-INF/views.xml"/>
    </beans:bean>

views.xml파일위치

views.xml파일을 만들어요. 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
   	<bean id="mr001_exceldownload_View" class="com.sms2019.excel.mr001_exceldownload_View" />
</beans>

views.xml
0.00MB

그리고 소스파일에 views.properties 추가를 해요. 

views.properties

mr001_exceldownload_View.(class)=com.sms2019.excel.mr001_exceldownload_View

views.properties
0.00MB

컨트롤러 부분에 요청받는 부분을 만들어요. 

@RequestMapping(value = "/g402_excel_download", method = RequestMethod.GET)
  public ModelAndView g402_excel_download(HttpServletRequest request, Model model) throws Exception {
	  	Util_list_convert smsp=Util_list_convert.getInstance();
	  	smsp.print_String("/gp/g402_excel_download");
		Map<String, String[]> paramMap=request.getParameterMap();
		paramMap.forEach(
				(key, value) ->  smsp.print_String(key + " : " + value[0])
				);
		Iterator keyData = paramMap.keySet().iterator();
		CommonData dto = new CommonData();	
		paramMap.forEach(
				(key, value) -> {dto.put(key, value[0]);
				smsp.print_String(key + " : " + value[0]);
				model.addAttribute(key,value[0].toString());
				});
	    CommonData data_box = new CommonData();
	    List Title_list = new ArrayList();    
	    Title_list.add("번호");
	    Title_list.add("품목명");
	    Title_list.add("규격");
	    Title_list.add("파트");
	    Title_list.add("수량");
	    Title_list.add("팀");

	    List Title_list_coll = new ArrayList();
	    Title_list_coll.add("rownum");
	    Title_list_coll.add("item_name");
	    Title_list_coll.add("item_standard");
	    Title_list_coll.add("part_division_text");
	    Title_list_coll.add("quantity");
	    Title_list_coll.add("team_code_text");
	    
	    dto.put("exceldown","exceldown");
	    List<Map<String, Object>> list = z_service.select(dto,"Gp2018_Mapper.g402_list_select");
	    ModelAndView mav = new ModelAndView("mr001_exceldownload_View");
	    mav.addObject("Title_list", Title_list);
	    mav.addObject("Title_list_coll", Title_list_coll);
	    mav.addObject("list", list);
	    mav.addObject("Filename", "주문목록");
	    return mav;
  }

엑셀 파일 데이터를 만들어요 db에서 읽어와도 좋고요 엑셀 윗부분을 요청 시 받아와도 되고요 전 컨트롤러를 각각 만들어서 써요. 그래서 타이틀이랑 항목 칼럼 이름 그리고 데이터 그리고 파일 이름 넣어요. 

그럼 MadelAndView에 적힌 부분으로 호출이 되는데요.

package com.danawa.excel;

import java.net.URLEncoder;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.view.document.AbstractExcelView;

import com.danawa.domain.CommonData;
import com.danawa.util.Util_list_convert;

@Controller
public class mr001_exceldownload_View extends AbstractExcelView {
 
    @Override
    protected void buildExcelDocument(Map<String, Object> model,
            HSSFWorkbook workbook, HttpServletRequest request, HttpServletResponse response)
            throws Exception {
    	Util_list_convert smsp=Util_list_convert.getInstance();
	  	smsp.print_String("Common_exceldownload");
    	String Filename = (String)model.get("Filename");
		String fileName = Filename+".xls";
		fileName = URLEncoder.encode(fileName,"UTF-8");
        response.setContentType("application/ms-excel; charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition","attachment; filename="+fileName);
        // get data model which is passed by the Spring container
        List<String> Title_list = (List<String>) model.get("Title_list");
        List<String> Title_list_coll = (List<String>) model.get("Title_list_coll");
    	List<CommonData> list = (List<CommonData>) model.get("list");
        // create a new Excel sheet
        HSSFSheet sheet = workbook.createSheet("sheet1");
        sheet.setDefaultColumnWidth(30);
         
        // create style for header cells
        CellStyle style = workbook.createCellStyle();
        CellStyle centerstyle = workbook.createCellStyle();
        CellStyle centerbluestyle = workbook.createCellStyle();
       
        Font font = workbook.createFont();
        font.setFontName("Arial");        
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        font.setColor(HSSFColor.WHITE.index);
       // style.setFillForegroundColor(HSSFColor.BLACK.index);
       // style.setFillPattern(CellStyle.SOLID_FOREGROUND);
        style.setBorderBottom (HSSFCellStyle.BORDER_THIN);
        style.setBottomBorderColor (HSSFColor.BLACK.index);
        style.setBorderLeft (HSSFCellStyle.BORDER_THIN);
        style.setLeftBorderColor (HSSFColor.BLACK.index);
        style.setBorderRight (HSSFCellStyle.BORDER_THIN);
        style.setRightBorderColor (HSSFColor.BLACK.index);
        style.setBorderTop (HSSFCellStyle.BORDER_THIN);
        style.setTopBorderColor (HSSFColor.BLACK.index);
        //style.setFont(font);        
        //centerstyle.setFillForegroundColor(HSSFColor.WHITE.index);
        //centerstyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
        centerstyle.setAlignment(CellStyle.ALIGN_CENTER);
        centerstyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        centerstyle.setBottomBorderColor(HSSFColor.BLACK.index);
        centerstyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        centerstyle.setLeftBorderColor(HSSFColor.BLACK.index);
        centerstyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
        centerstyle.setRightBorderColor(HSSFColor.BLACK.index);
        centerstyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
        centerstyle.setTopBorderColor(HSSFColor.BLACK.index);
        centerbluestyle.setFillForegroundColor(HSSFColor.BLACK.index);
        centerbluestyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
        centerbluestyle.setAlignment(CellStyle.ALIGN_CENTER);
        centerbluestyle.setFillBackgroundColor(HSSFColor.BLACK.index);
        centerbluestyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        centerbluestyle.setBottomBorderColor(HSSFColor.BLACK.index);
        centerbluestyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        centerbluestyle.setLeftBorderColor(HSSFColor.BLACK.index);
        centerbluestyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
        centerbluestyle.setRightBorderColor(HSSFColor.BLACK.index);
        centerbluestyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
        centerbluestyle.setTopBorderColor(HSSFColor.BLACK.index);
        centerbluestyle.setFont(font);    
         
        // create header row
        HSSFRow header = sheet.createRow(0);
        
        int cellCount;
        cellCount=0;
        int columns_length=0;
        //제목 값 세팅 한다. 
        for(String item : Title_list){
        	header.createCell(cellCount).setCellValue(item);
            header.getCell(cellCount).setCellStyle(centerbluestyle);
            cellCount++;
            columns_length++;
    	}
        
        // create data rows
        int rowCount = 1;   
        String sitem_name = null;
        String item_standard = null;
        String sitem_name_replace=null;
        Iterator list_object = list.iterator();	    
        while (list_object.hasNext()) {
        	CommonData e_object = (CommonData) list_object.next();
            HSSFRow aRow = sheet.createRow(rowCount++);
            cellCount=0; 
            
            for(String item : Title_list_coll){
                String value = e_object.get(item);
                smsp.print_String("item : " + value);
                aRow.createCell(cellCount).setCellValue(value);
	            aRow.getCell(cellCount).setCellStyle(centerstyle);            
	            cellCount++;
            }
    	}
        for(int ni=1;ni<=sheet.getLastRowNum();ni++)
        { 
        	sheet.getRow(ni).setHeightInPoints((float)20);
        	 
        }
       
        autoSizeColumns(sheet,sheet.getRow(0).getLastCellNum());
    }
    private void autoSizeColumns(HSSFSheet sheetData, int maxColNum) {
   	 try {
   		 // Autosize columns
   		 int width = 0;
   		 for (int col = 0; col < maxColNum; col++) {
   			 sheetData.autoSizeColumn(col);
   			 int cwidth = sheetData.getColumnWidth(col);
   			 cwidth += 500;
   			 sheetData.setColumnWidth(col, cwidth);
   			 width += cwidth;
   		 }

   		 // calculate zoom factor
   		 int nominator = 45000 * 100 / width;
   		 if (nominator < 100)
   			 sheetData.setZoom(nominator, 100);

   	 } catch (Exception he) {
   		 // No UI, no autosize :(
   	 }
    }
 
}

이렇게 엑셀 내용을 채워 엑셀 파일이 만들어져요.

String Filename = (String)model.get("Filename");
		String fileName = Filename+".xls";
		fileName = URLEncoder.encode(fileName,"UTF-8");
        response.setContentType("application/ms-excel; charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition","attachment; filename="+fileName);

파일 이름을 설정하고 utf8로 다운로드돼요.

List<String> Title_list = (List<String>) model.get("Title_list");
        List<String> Title_list_coll = (List<String>) model.get("Title_list_coll");
    	List<CommonData> list = (List<CommonData>) model.get("list");

엑셀 파일의 항목 타이틀과 각 항목의 column의 이름 그리고 데이터 받아와요. 

HSSFSheet sheet = workbook.createSheet("sheet1"); 
        sheet.setDefaultColumnWidth(30);

sheet를 만들어요. 만들 때 이름을 정해줄 수 있어요. 전 sheet1이라고 했어요. 

// create style for header cells
        CellStyle style = workbook.createCellStyle();
        CellStyle centerstyle = workbook.createCellStyle();
        CellStyle centerbluestyle = workbook.createCellStyle();
       

cell 스타일을 미리 만들었어요.  단순해요. style는 흰색의 배경에 검은색의 테두리 선을 가진 것이고요. centerstyle는 중앙 정렬한 흰색 배경에 검은색 테두리 구요. centerbluestyle는 중앙 정렬에 파란 배경을 과 검은색 테두리를 가진 스타일이에요. 

style.setBorderBottom (HSSFCellStyle.BORDER_THIN);
        style.setBottomBorderColor (HSSFColor.BLACK.index);
        style.setBorderLeft (HSSFCellStyle.BORDER_THIN);
        style.setLeftBorderColor (HSSFColor.BLACK.index);
        style.setBorderRight (HSSFCellStyle.BORDER_THIN);
        style.setRightBorderColor (HSSFColor.BLACK.index);
        style.setBorderTop (HSSFCellStyle.BORDER_THIN);
        style.setTopBorderColor (HSSFColor.BLACK.index);        
        centerstyle.setAlignment(CellStyle.ALIGN_CENTER);
        centerstyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        centerstyle.setBottomBorderColor(HSSFColor.BLACK.index);
        centerstyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        centerstyle.setLeftBorderColor(HSSFColor.BLACK.index);
        centerstyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
        centerstyle.setRightBorderColor(HSSFColor.BLACK.index);
        centerstyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
        centerstyle.setTopBorderColor(HSSFColor.BLACK.index);
        centerbluestyle.setFillForegroundColor(HSSFColor.BLACK.index);
        centerbluestyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
        centerbluestyle.setAlignment(CellStyle.ALIGN_CENTER);
        centerbluestyle.setFillBackgroundColor(HSSFColor.BLACK.index);
        centerbluestyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        centerbluestyle.setBottomBorderColor(HSSFColor.BLACK.index);
        centerbluestyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        centerbluestyle.setLeftBorderColor(HSSFColor.BLACK.index);
        centerbluestyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
        centerbluestyle.setRightBorderColor(HSSFColor.BLACK.index);
        centerbluestyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
        centerbluestyle.setTopBorderColor(HSSFColor.BLACK.index);
        centerbluestyle.setFont(font);    

직관적으로 만들어놓아서 대충 알아보실 거 같아요. 소스량을 줄이려면 함수를 만들면 되겠죠? 그건 직접 해보세요 ^^

 Font font = workbook.createFont();
        font.setFontName("Arial");        
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        font.setColor(HSSFColor.WHITE.index);

폰트를 따로 선언해서 사용해야 할 일이 있을 경우엔 폰트도 추가해주세요 전 타이틀 부분은 폰트를 다르게 했어요 흰색으로요. ^^

HSSFRow header = sheet.createRow(0);

첫 번째 로우를 만들고요 

 int cellCount;
        cellCount=0;
        int columns_length=0;
        //제목 값 세팅 한다. 
        for(String item : Title_list){
        	header.createCell(cellCount).setCellValue(item);
            header.getCell(cellCount).setCellStyle(centerbluestyle);
            cellCount++;
            columns_length++;
    	}

첫번째 행에 항목 타이틀 값들을 넣어줘요... 

 // create data rows
        int rowCount = 1;   
        String sitem_name = null;
        String item_standard = null;
        String sitem_name_replace=null;
        Iterator list_object = list.iterator();	    
        while (list_object.hasNext()) {
        	CommonData e_object = (CommonData) list_object.next();
            HSSFRow aRow = sheet.createRow(rowCount++);
            cellCount=0; 
            
            for(String item : Title_list_coll){
                String value = e_object.get(item);
                smsp.print_String("item : " + value);
                aRow.createCell(cellCount).setCellValue(value);
	            aRow.getCell(cellCount).setCellStyle(centerstyle);            
	            cellCount++;
            }
    	}

컨트롤러에서 넘겼던 칼럼 항목 이름을 순으로 위치로 해서 셀에 넣어요. 

이상으로 엑셀 파일 다운로드 관련해서 정리해보았습니다. 

블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,

홈페이지를 구축하다보면 기존 도메인과 개발도메인 로컬 도메인등 여러 주소를 사용할 경우가 있습니다.

저의 경우 홈페이지 구매후 신규 개발을 들어 갔는데 이름역시 디지털아트에서 디지털365치과의원으로 변경되어 

홈페이지를 신규개발한후 365에 맞는 도메인 https://digital365365.com/ 를 구매하여 설정하였고

기존에 운영중인던 도메인 dadentalclinic.com 도메인과 디지털365치과.com 등을 추가로 설정하였습니다.

그런데 블로그나 사이트 등록시 https://digital365365.com/ 로 하면 좋았을텐데 여러가지 도메인들을 사용하게 되었습니다.

그래서 도메인을 임의로 통합시키는 작업을 해주었습니다. 

<beans:bean id="metaInterceptor" class="com.sms2019.interceptor.MetaInterceptor"></beans:bean>

인터셉터 를 하나 만들어 줍니다. 

인터셉터 내용은 아래와 같습니다.

String m_url = request.getRequestURL().toString();
		smsp.print_String("m_url :" + m_url);
		if(m_url.contains("검사주소 넣기"))
		{
			smsp.print_String("바른주소");
		}
		else if(m_url.contains("http://localhost"))
		{
			smsp.print_String("로콜주소");
		}
		else
		{
			smsp.print_String("그외 주소다.");
			String new_addr = "https://digital365365.com"+originalURL;
			response.sendRedirect(new_addr);
		}

이상입니다. 

블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,