Programing/Java & Spring

Spring MVC를 이용하여 웹 페이지 제작 vo4 : Bootstrap을 이용해서 디자인 및 FileIO [File 입출력, Json, JqGrid 등]

세기루민 2021. 1. 20. 10:56
728x90

sg-moomin.tistory.com/48

 

Spring MVC를 이용하여 웹 페이지 제작 vo3 : Json File을 연결한 후 view(jsp)를 이용하여 확인해보자.

sg-moomin.tistory.com/45 Spring MVC를 이용하여 웹 페이지 제작 vo2 : spring 초기 설정을 해보자 sg-moomin.tistory.com/44 Spring MVC를 이용하여 웹 페이지 제작 vo1 : Spring MVC을 이해하자 우선 Spring Mv..

sg-moomin.tistory.com

우선 전에 포스팅을 못본 분들은 위에서 확인!


전 포스팅에서는 기본적인 Controller -> Service -> Store 과정을 다뤘는데

오늘은 직접 데이터를 입력해보고 View단을 꾸며보도록 하겠습니다.


1. BootStrap!

View를 말한다면 Html이나 Jsp, css 등등

다양한 파일들이 존재하는데 직접 구성해도 좋지만 실력이 그렇지 못하다면......

사실상 페이지의 view가 이쁘지 않을 것이다.

이런 사람들을 위해 자주 사용되는 BootStrap을 소개해보면

getbootstrap.com/

 

Bootstrap

The most popular HTML, CSS, and JS library in the world.

getbootstrap.com

위에 사이트에서 직접 다운로드 받고 사용이 가능합니다.

위의 사이트를 들어가면 이런 창이 뜨는데 Download를 해서 사용해도 되고

예시로 제공해주는 툴을 변형해서 사용해도 됩니다.

저는 여기서 예시를 변형해서 사용해보도록 하겠습니다.

우선 제가 사용할 툴은 CheckOut!

여기서 index.html을 변형할 예정입니다.

추가적으로 BootStrap Zip파일을 다운로드를 같이 받은 후

bootstrap.min.css와 같이 기본파일들을 Eclipse에 넣어주면 됩니다.

저의 경우는 WebContent -> resources -> css or js로 구분해서 관리했습니다.

추가적으로 grid를 사용하기 위해 grid와 관련된 설정파일을 넣어뒀습니다.

www.guriddo.net/demo/bootstrap/

 

Guriddo jqGrid - jQuery based grid HTML5 component for Javascript

Edit form with custom template New Cache dataUrl New Dialogs: edit Controls (datepicker, autocomplete, dropdown, checkbox, custom, etc) Dialogs: Edit, Add, Delete Dialogs: Custom Layout Dialogs: Linked / Dependent dropdowns Dialogs: Validation - client-sid

www.guriddo.net

제가 그리드를 파일들을 참고한 사이트는 위에 링크 달아뒀습니다!


2.Code 구성

전 포스팅에서는 단순하게 파일을 테이블로 보여줬는데

이번에는 bootStrap을 이용해서 나름 깔쌈하게 만들어 보겠습니다.

위에 예제 툴은 원하시는 걸로 사용하면 됩니다. 


제가 참고할 BootStrap을 이용한 HTML 코드를 먼저 보여드리면! 

index.html
0.01MB

 

위의 코드를 참고해서 아래에 Main을 만들어줍니다.

Main.jsp(check.jsp)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <title>Checkout example · Bootstrap v5.0</title>
    <link rel="canonical" href="https://getbootstrap.com/docs/5.0/examples/checkout/">

    <!-- Bootstrap core CSS -->
	<link href="${pageContext.request.contextPath}/resources/css/bootstrap.min.css" rel="stylesheet">
	<!-- Grid css & js -->
	<script type="text/ecmascript"
	src="${pageContext.request.contextPath}/resources/js/jquery.min.js"></script>
	<script type="text/ecmascript"
		src="${pageContext.request.contextPath}/resources/js/i18n/grid.locale-en.js"></script>
	<script type="text/ecmascript"
		src="${pageContext.request.contextPath}/resources/js/jquery.jqGrid.min.js"></script>
	<link rel="stylesheet" type="text/css" media="screen"
		href="${pageContext.request.contextPath}/resources/css/ui.jqgrid-bootstrap.css" />
	<script>
	$.jgrid.defaults.responsive = true;
	$.jgrid.defaults.styleUI = 'Bootstrap';
	</script>
	<!-- Style -->
    <style>
      .bd-placeholder-img {
        font-size: 1.125rem;
        text-anchor: middle;
        -webkit-user-select: none;
        -moz-user-select: none;
        user-select: none;
      }

      @media (min-width: 768px) {
        .bd-placeholder-img-lg {
          font-size: 3.5rem;
        }
      }
    </style>
    
	<script src="${pageContext.request.contextPath}/resources/css/form-validation.css"></script>
  </head>
  <body class="bg-light">
    
<div class="container">
  <main>
    <div class="py-5 text-center">
      <h2>새벽 기상을 꿈꾸는 무민</h2>
      <p class="lead">IT 이슈와 개발을 하고 있는 취준생이며 현재는 루민이의 일상이라는 블로그를 운영하면서 열심히살아가고 있는 청년입니다.</p>
<p class="lead">취미 : 맛집과 아메리카노를 탐방하러 다니는 걸 좋아합니다. NaverBlog : https://blog.naver.com/rooney9325</p> 
<p class="lead">TistoryBlog : https://sg-moomin.tistory.com </p>
 <p class="lead">instagram: Romin_pic (새로 시작했어요~) </p>
<p class="lead">#취준생#IT#정보보안#일상#공대생#취준일기#커피#사진 #음식사진 </p>
    </div>

    <div class="row g-3">
      <div class="col-md-7 col-lg-8 order-md-last">
        <h4 class="d-flex justify-content-between align-items-center mb-3">
          <span class="text-muted">Your cart</span>
          <span class="badge bg-secondary rounded-pill">3</span>
        </h4>
        <div class="table-responsive">
			<table class="table table-striped table-sm" id="GridList"></table>
			<div id="jqGridPager"></div>
		</div>
        
      </div>
      <div class="col-md-5 col-lg-4">
        <h4 class="mb-3">정보 입력</h4>
        <form class="needs-validation" action="${pageContext.request.contextPath}/moomin/createCheck.do">
          <div class="row g-3">
            <div class="col-12">
              <label for="Name" class="form-label">Name <span class="text-muted"></span></label>
              <input type="text" class="form-control" id="userName" name="userName" placeholder="sg-moomin">
            </div>

            <div class="col-12">
              <label for="Number" class="form-label">Number</label>
              <div class="input-group">
                <span class="input-group-text">010</span>
                <input type="text" class="form-control"  id="userNumber" name="userNumber"placeholder="Number" required>
              </div>
            </div>

            <div class="col-12">
              <label for="email" class="form-label">Email <span class="text-muted">(Optional)</span></label>
              <input type="email" class="form-control" id="email" name="email"placeholder="you@example.com">
             
            </div>
          </div>
          <hr class="my-4">
          <input id="checkBtn" class="w-100 btn btn-primary btn-lg" type="submit">Continue to checkout</input>
        </form>
      </div>
    </div>
  </main>
</div>

    <script src="${pageContext.request.contextPath}/resources/js/bootstrap.bundle.min.js"></script>
	<script src="${pageContext.request.contextPath}/resources/js/form-validation.js"></script>
  		<script>
        var temp = new Array();
        temp = ${temp};
  		</script>
        
        <script type="text/javascript">
        $(document).ready(function(){
        	$("#GridList").jqGrid({
        		url : "moomin/check.do",
				data : temp,
                mtype: "GET",
                datatype: "local",
                colNames:[
                	'index', '전화번호','이름','이메일'],
                colModel:[  	
                	{label:'index',name:'index', align:'center'},
                    {label:'전화번호',name:'number', align:'center'},
                    {label:'이름',name:'name', align:'center'},
                    {label:'이메일',name:'email', align:'center'}
                   ],	
				// width: "100%",
				// height: "100%",
				rowNum: 30,
				scrollLeftOffset: "83%",
				viewrecords: true,
				loadonce: true, 
                autowidth:true,
                autoheight:true,
                pager: "#jqGridPager"
        	});	
        });
        for(var I in temp){
	           $("#GridList").jqGrid('addRowData',i+1,temp[i]);
	     }
        $(window).resize(function() {

        	$("#GridList").setGridWidth($(this).width() * .100);
        	$("#GridList").setGridWidth($(this).height() * .100);

        });
        </script>
  </body>
</html>

index.html을 이용해서 main을 수정해줍니다. 

사실상 class를 직접 만들지 않았구 css나 js를 이용하기 때문에 그대로 사용해줍니다. 

직접 추가한 부분은 Grid를 만들어주기 위해 Script를 제작해줍니다. 

주의해야 할 점은 colModel의 Name이 일치하지 않는 경우에는 데이터가 재대로 출력되지 않습니다.

html파일을 보면 경로 설정이 ${pageContext.request.contextPath}로 구성되지 않을 것입니다.

${pageContext.request.contextPath}를 이용하면 ContextPath가 변경 시 유지보수가 좋기 때문에 

${pageContext.request.contextPath}를 사용해서 직접 프로젝트 내 경로로 변경해줍니다.


MainController.Java

@Controller
@RequestMapping("moomin")
public class mainController {

	@Autowired
	private userService user;
	
	@RequestMapping(value = "check.do", method= RequestMethod.GET)
		public String check(Model model) throws IOException, ParseException {
		ArrayList<user> userJsonList = new ArrayList<user>();
		userJsonList = user.selectJsonUser();	
		Gson gson = new Gson();
		
		model.addAttribute("temp", gson.toJson(userJsonList));
		model.addAttribute("JsonData", userJsonList);

	return "main/check";
	}
	
	
	@RequestMapping(value = "createCheck.do", method= RequestMethod.GET)
	public String createCheck(Model model, user moomin) throws IOException, ParseException {
		user.insertUser(moomin);
		ArrayList<user> userJsonList = new ArrayList<user>();
		userJsonList = user.selectJsonUser();	
		Gson gson = new Gson();
		
		model.addAttribute("temp", gson.toJson(userJsonList));
		model.addAttribute("JsonData", userJsonList);
		return "main/check";
	}
	
}

 

Check.do와 CreateCheck.do를 사용하는데

Check.do는 기존에 Main.do와 같은 역활을 하고 

createCheck.do는 파일을 생성 시 사용되는 컨트롤러 입니다. 

컨트롤러는 명령에 따라서 Store까지 움직이게 되구 

결과를 Gson -> Json을 이용해서 View로 전달해주게 됩니다. 

Json으로 전달하면 Check.jsp(main.jsp)에서 Grid로 보여주게 됩니다.


userServiceLogic.Java

@Service
public class userServiceLogic implements userService{

	@Autowired
	private userJson userJ;
	
	@Override
	public ArrayList<user> selectJsonUser() throws IOException, ParseException {
		return userJ.selectJUser();
	}

	@Override
	public void insertUser(user list) throws IOException, ParseException {
		StringBuffer temp = new StringBuffer(list.getUserNumber());
		temp.insert(0, "010-");
		list.setUserNumber(temp.substring(0));
		// System.out.println("insert buffer : " + list.getUserNumber());
		
		userJ.insertUser(list);
	}

}

ServiceLogic을 보면 insertUser부분에서 

StringBuffer를 이용해서 "010-"을 추가해주게 됩니다 .

이 부분은 Jsp 구성 시 전화번호를 입력받을 시 010을 제외하고 입력하기 때문에 

ServiceLogic에서 지정해줍니다. 

추가적으로 insert에서도 parserException과 IOException 예외처리를 해줍니다. 

파서랑 파일 입출력을 이용해야하기 때문!

public void insertUser(user list) throws IOException, ParseException;

위에 처럼 serService Interface도 예외처리를 해주면 됩니다.


userJsonLogic.Java

이번 포스팅에서 가장 중요한 건 Store 부분입니다. 

은근 삽질을 오지게 해서...ㅎ

@Repository
public class userJsonLogic implements userJson{
	
	File file = new File("자신이 Json 파일을 저장하려는 경로를 입력해주면 됩니다.");
	JSONParser jsonParser = new JSONParser();
		
	public JSONObject jsonPut(int count, user userList) {
		JSONObject JObject = new JSONObject();
		JObject.put("index", count);
		JObject.put("name", userList.getUserName());
		JObject.put("number", userList.getUserNumber());
		JObject.put("email", userList.getEmail());
		return JObject;
	}
	
	
	public ArrayList<user> selectJUser() throws IOException, ParseException{
		ArrayList<user> userList = new ArrayList<user>();
		FileInputStream  fileInputStream = new FileInputStream(file);
		InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "MS949");
		BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

		
		if(bufferedReader.ready() == false) {
			return null;
		}

		String str = bufferedReader.readLine();
		JSONParser parser = new JSONParser();
		Object obj = parser.parse(str);
		JSONArray jArray = (JSONArray) obj;
		userList.addAll(jArray);
		
		return userList;
	
	}

	@Override
	public void insertUser(user list) throws IOException, ParseException {
		FileInputStream fileInputStream = new FileInputStream(file);
		InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "MS949");
		BufferedReader bufferReader = new BufferedReader(inputStreamReader);
		
		JSONArray jsonArray = new JSONArray();
		
		String str = bufferReader.readLine();
		if(str == null) {
			int count = jsonArray.size();
			JSONObject jsonDAO = jsonPut(count, list);
			jsonArray.add(jsonDAO);		
		} else {
			JSONParser parser = new JSONParser();
			Object obj = parser.parse(str);
			JSONArray jArray = (JSONArray) obj;
			
			for(int i = 0; i < jArray.size(); i++) {
				jsonArray.add((JSONObject)jArray.get(i));				
			}
			int count = jsonArray.size();
			JSONObject jsonDAO = jsonPut(count, list);
			jsonArray.add(jsonDAO);				
		}
		
		FileOutputStream fileOutputStream = new FileOutputStream(file);
		OutputStreamWriter OutputStreamWriter = new OutputStreamWriter(fileOutputStream, "MS949");
		BufferedWriter bufferedWriter = new BufferedWriter(OutputStreamWriter);
		
		bufferedWriter.write(jsonArray.toJSONString());
		bufferedWriter.flush();
		bufferedWriter.close();

	}

	
}

 

우선 jsonPut이라는 매소드는 쉽게 설명하자면 

Json 객체를 생성하는 메소드입니다. 

이것을 만든 이유는 insert에서 지속적으로 사용되기 때문에!

먼저 InsertUser!

FileInputStream -> InputStreamReader -> BufferReader를 이용해서 객체화를 하여 출력해줍니다. 

bufferReader.readLine()을 하면 객체화 된 파일에 다음라인을 읽어오는데 

만약에 없는 경우에는 오류가 발생할 수 있다. 

즉 처음에 실행할 때 오류가 발생하기 때문에 조건문을 이용해서 

처음 만든 경우에는 JsonArray에 객체를 넣어주고 

기존에 존재한다면 해당 존재하는 값을 JsonArray에 옮긴 후 입력받은 객체를 넣어주면 된다. 

존재하는 값을 JsonArray에 넣어주는 이유는 

FileinputStream으로 객체를 생성시 기존 데이터가 존재했을 때 추가하는게 아니라 덮어쓰게 된다. 

따라서 추가하기 위해서 Fileinput -> bufferedReader.readLine() -> JsonArray -> FileOutPut

위의 과정을 거치면 된다. 

마지막으로 Select!

전 포스팅에서 했던 코드랑은 조금 다를 것이다. 

똑같이 FileInputStream -> InputStreamReader -> BufferReader를 이용해서 객체화된 Byte를 출력해줍니다. 

이때 처음에 값이 없다면 null을 리턴해줍니다. 

그렇지 않는 경우에는 오류가 발생하기 때문입니다. 

파일로부터 받은 BufferedReader.readLine() 값을 다시 파싱하여 객체 변환 후  JsonArray에 넣어주고

user 배열에 값을 넣어준 후 반환하면 끝이다.  


3. 결과

우선 기본 페이지를 볼 수 있다. 

처음에는 cart라는 부분에 아무 값이 없는데 이는 Json으로 저장된 값이 없기 때문!

위의 값을 입력 후 제출하면

Grid로 추가된 값을 확인할 수 있고 

계속 추가가 가능한 걸 확인할 수 있다. 

또한 Json 파일을 저장한 경로가 WebContent -> Json 폴더 내부에 저장했고 

위처럼 저장되는 것을 확인할 수 있다.


오늘은 FileIO 사용과 Json을 이용하여 데이터를 입출력해봤습니다.

다음에는 더 유익하고 좋은 정보로 찾아오겠습니다. 

728x90