[ Spring Boot ] Spring Boot Sample 본문

[PL]/JAVA

[ Spring Boot ] Spring Boot Sample

객과 함께. 2016. 11. 22. 23:45


환경: java 1.8 , postgresql 9.x , thymeleaf , angularjs ,  windows 10 


IndexController.java 

package org.example.Controller;


import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;


@Controller

public class IndexController {

@RequestMapping(value="/" , method=RequestMethod.GET)

public String main() {

return "redirect:/Demo/view/index";

}

}


zipItemController.java

package org.example.Controller;


import org.example.Service.zipItemService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;


@Controller

@RequestMapping(value="/Demo/view")

public class zipItemController 

@RequestMapping(value="zipItem/list", method=RequestMethod.GET)

public String itemList() {

return "zipItem/list";

}

}


zipItemDto.java

package org.example.Dto;


import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.NotBlank;


import lombok.Data;


public class zipItemDto {


@Data

public static class zCreate {

@NotBlank

@Size(min=1 , max=10)

private String zname;

}

@Data

public static class zResponse {

private int zid;

private String zname;

}

@Data

public static class zUpdate {

private String zname;

}

}


zipItem.java

package org.example.Model;


import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;


import lombok.Getter;

import lombok.Setter;


@Getter

@Setter

@Entity(name="zipitem")

public class zipItem {


@Id   @GeneratedValue(strategy=GenerationType.AUTO)

private int zid;

private String zname;

}



zipItemRepository.java

package org.example.Repository;


import java.util.List;

import org.example.Model.zipItem;

import org.springframework.data.domain.Page;

import org.springframework.data.domain.Pageable;

import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.data.jpa.repository.Query;

import org.springframework.data.repository.query.Param;

import org.springframework.transaction.annotation.Transactional;



@Transactional

public interface zipItemRepository extends JpaRepository<zipItem, Integer> {


zipItem findOne(Integer zid);

       // Select zid from zipitem where zid= ? 

//List<zipItem> findByZnameOrderByZidDesc(String zname , Pageable pageable);


@Query("select u from zipitem u where u.zname like :zname||'%'")

Page<zipItem> findByZnameLike(@Param("zname") String zname, Pageable pageable );

        // select zid , zname from zipitem where zname like ' zname%' order by zid offset = 0 limit = 10;

}



zipItemRestController.java

package org.example.Rest;


//import java.io.Console; // TODO DEBUG

import java.util.List;

import java.util.stream.Collectors;


import javax.validation.Valid;

import org.example.Dto.zipItemDto;

import org.example.Model.zipItem;

import org.example.Repository.zipItemRepository;

import org.example.Service.zipItemService;

import org.modelmapper.ModelMapper;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.domain.Page;

import org.springframework.data.domain.PageImpl;

import org.springframework.data.domain.Pageable;

import org.springframework.http.HttpStatus;

import org.springframework.http.ResponseEntity;

import org.springframework.validation.BindingResult;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.RestController;



@RestController

@RequestMapping(value="/Demo/zipItem")

public class zipItemRestController {


Logger logger = LoggerFactory.getLogger(this.getClass());

@Autowired

private ModelMapper mapper;

@Autowired

private zipItemService service;

@Autowired

private zipItemRepository repository;

@SuppressWarnings("rawtypes")

@RequestMapping(value="save" , method=RequestMethod.POST , consumes = "application/json" )

public ResponseEntity ItemSave(@RequestBody @Valid zipItemDto.zCreate create ,BindingResult result) {

logger.debug("========================= 1");

if(result.hasErrors()) {

logger.debug("========================= 2");

return new ResponseEntity<>(result.getAllErrors() , HttpStatus.BAD_REQUEST);

}

zipItem newzipItem = service.createZipItem(create);

return new ResponseEntity<>(mapper.map(newzipItem, zipItemDto.zResponse.class), HttpStatus.CREATED);

}

// TODO 페이징을 지원 pageable (Spring framework4.3 참조)

@SuppressWarnings("rawtypes")

@RequestMapping(value="list", method=RequestMethod.GET)

public ResponseEntity ItemList(Pageable pageable) {

Page<zipItem> page =  repository.findAll(pageable);

List<zipItemDto.zResponse> content = page.getContent().parallelStream()

.map(zipItem -> mapper.map(zipItem, zipItemDto.zResponse.class,  "zipItem/list"))

.collect(Collectors.toList());

System.out.println("===============" + content);

PageImpl<zipItemDto.zResponse> result = new PageImpl<>(content , pageable , page.getTotalElements());

return new ResponseEntity<>(result , HttpStatus.OK);

}

@SuppressWarnings("rawtypes")

@RequestMapping(value="search", method=RequestMethod.POST  )

public ResponseEntity ItemSearch(Pageable pageable , @RequestParam(value="zname") String zname) {

//System.out.println("===============" + zname);

Page<zipItem> page =  repository.findByZnameLike(zname, pageable);

System.out.println("===============" + page.getTotalElements());

List<zipItemDto.zResponse> content = page.getContent().parallelStream()

.map(zipItem -> mapper.map(zipItem, zipItemDto.zResponse.class,  "zipItem/search"))

.collect(Collectors.toList());

System.out.println("===============" + content);

PageImpl<zipItemDto.zResponse> result = new PageImpl<>(content , pageable , page.getTotalElements());

return new ResponseEntity<>(result , HttpStatus.OK);

}

@SuppressWarnings("rawtypes")

@RequestMapping(value="delete/{id}" , method=RequestMethod.DELETE)

public ResponseEntity deleteItem(@PathVariable Integer id) {

service.DeleteZipItem(id);

return new ResponseEntity<>(HttpStatus.NO_CONTENT);

}

}


zipItemService.java

package org.example.Service;


import org.example.Dto.zipItemDto;

import org.example.Model.zipItem;

import org.example.Repository.zipItemRepository;

import org.modelmapper.ModelMapper;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;



@Service

public class zipItemService {


@Autowired

private zipItemRepository repository;

@Autowired

private ModelMapper mapper;

public zipItem createZipItem(zipItemDto.zCreate zitem)  {

zipItem zipitem = mapper.map(zitem, zipItem.class);

return repository.save(zipitem);

}

public void DeleteZipItem(Integer id) {

repository.delete(id);

}



list.html

<!DOCTYPE html>

<html th:xnlns="http://www.thymeleaf.org">

<head>

<meta charset="utf-8" />

<title>Insert title here</title>

<link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css"/>

<link rel="stylesheet" href="/css/myCss.css"/>

</head>

<body ng-app="myZitItem" ng-controller="myZipItemController">

<div class="col-md-1\6 col-sm-6 col-xs-6">

<div class="panel panel-danger spacer">

<div class="panel-heading"><h3><b>= 입력란 =</b></h3></div>

<div class="panel-body">

<form>

<div class="form-group">

<label> Name :</label>

<input type="text" ng-model="zname" placeholder="Input here write Name" />

<button ng-click="chargerSave()">Save</button>

</div>

</form>

<h5>

<!-- <table class="table table-striped"> -->

<table class="table table-condensed">

<thead>

<tr>

<th>NUM</th><th>NAME</th><th></th>

</tr>

</thead>

<tbody ng-repeat="item in zipItems.content">

<tr>

<td class="no">{{$index + 1}}</td>

<td class="width">{{item.zname}}</td>

<td style="display:none">{{item.zid}}</td>

<td class="no">

<button ng-click="chargerDelete(item)" class="btn btn-danger btn-xs"><i class="glyphicon glyphicon-trash

"></i></button>

</td>

</tr>

</tbody>

</table>

</h5>

<!-- 1.  페이징 시작 -->

<!-- <div class="container spacer">

<ul class="nav nav-pills">

<li class="clickable" ng-class="{active:$index==pageCourante}" ng-repeat="p in pages track by $index">

<a ng-click="goTopage($index)">{{$index}}</a>

</li>

</ul>

</div> -->

<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////// -->

<div class="panel panel-default spacer">

<form name="comboIndex">

<label>현제 페이지 :</label>    

<select ng-model="valIndex">

<option ng-repeat="p in pages track by $index" ng-value="{{$index}}" ng-selected="{{$index.Selected == true}}" >{{$index}}</option>

</select>

   /    {{totalPages}}   

<button ng-click="chargerMove(valIndex)" class="btn btn-danger btn-xs"> 이동 </button>

</form>

</div>

<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////// -->

<!-- 페이징 끝 -->

</div>

</div>

 

</div>

<div class="col-md-6 col-sm-6 col-xs-6">

<div class="panel panel-danger spacer">

<div class="panel-heading"><h3><b>입력 검색</b></h3></div>

<div class="panel-body">

<form>

<div class="form-group">

<label> Name :</label>

<input type="text" ng-model="zname1" placeholder="

Name to search" />

<button ng-click="chargerSearch(zname1)">Search</button>

</div>

</form>

<div class="panel panel-success spacer">

<table class="table table-condensed">

<thead>

<tr>

<th>NO.</th><th>NAME</th><th>ID</th>

</tr>

</thead>

<tbody ng-repeat="z3 in zipItems1.content">

<tr>

<td class="no">{{$index + 1}}</td>

<td class="width">{{z3.zname}}</td>

<!-- <td style="display:none">{{item3.zid}}</td> -->

<td>{{z3.zid}}</td>

<td class="no">

<!-- <button ng-click="chargerDelete(z3)" class="btn btn-danger btn-xs"><i class="glyphicon glyphicon-trash

"></i></button> -->

</td>

</tr>

</tbody>

</table>

</div>

<div>

<!-- ////////////////////////////////////////////////////////////////////////// -->

  <form name="comboIndex">

<label>현제 페이지 :</label>    

<select ng-model="valIndex1">

<option ng-repeat="p1 in pages1 track by $index" ng-value="{{$index}}" ng-selected="{{$index.Selected == true}}" >{{$index}}</option>

</select>

   /    {{totalPages1}}   

<button ng-click="chargerSearch1(valIndex1 , zname1)" class="btn btn-danger btn-xs"> 이동 </button>


</form>

<!-- ////////////////////////////////////////////////////////////////////////// -->

</div>

</div>

</div>

</div>

<div class="col-md-6 col-sm-6 col-xs-12">

<div class="panel panel-danger spacer">

<div class="panel-heading"><h3><b>이 프로젝트 목표</b></h3></div>

<div class="panel-body">

<div class="panel panel-default spacer">

TEST

</div>

<div class="panel panel-info spacer">

Test 1

</div>

<div class="panel panel-primary spacer">

Test 2

</div>

<div class="panel panel-success spacer">

Test 3

</div>

<div class="panel panel-warning spacer">

Test 4

</div>

<div class="panel panel-danger spacer">

Test 5

</div>

</div>

</div>

</div>

<div class="col-md-6 col-sm-6 col-xs-12">

<div class="panel panel-danger spacer">

<div class="panel-heading"><h3><b>TEST 3</b></h3></div>

<div class="panel-body">

<div class="panel panel-default spacer">

test 0

</div>

<div class="panel panel-info spacer">

Test 1

</div>

<div class="panel panel-primary spacer">

Test 2

</div>

<div class="panel panel-success spacer">

Test 3

</div>

<div class="panel panel-warning spacer">

Test 4

</div>

<div class="panel panel-danger spacer">

Test 5

</div>

</div>

</div>

</div>

<div class="col-md-12 col-sm-12 col-xs-12">

        <p class="panel panel-success text-center ">

            <small><strong> Web Rest API Test</strong></small><br />

            <small>Copyrightⓒ kisco98. All rights reserved.</small>

        </p>

</div>

<script src="/angular/angular.min.js"></script>

<script src="/js/myApp.js"></script>

</body>

</html>


POM.XML

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>


<groupId>org.example</groupId>

<artifactId>SpringBootDemo02</artifactId>

<version>0.0.1-SNAPSHOT</version>

<packaging>war</packaging>


<name>SpringBootDemo02</name>

<description>Demo project for Spring Boot And Session</description>


<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>1.4.0.RELEASE</version>

<relativePath /> <!-- lookup parent from repository -->

</parent>


<properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<java.version>1.8</java.version>

</properties>


<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-jpa</artifactId>

</dependency>

<dependency>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-thymeleaf</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<dependency>

<groupId>org.postgresql</groupId>

<artifactId>postgresql</artifactId>

<scope>runtime</scope>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-tomcat</artifactId>

<scope>provided</scope>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>


<!-- Util -->

<dependency>

<groupId>org.modelmapper</groupId>

<artifactId>modelmapper</artifactId>

<version>0.7.5</version>

</dependency>

<dependency>

<groupId>org.codehaus.jackson</groupId>

<artifactId>jackson-mapper-asl</artifactId>

<version>1.9.7</version>

</dependency>


<dependency>

<groupId>org.codehaus.jackson</groupId>

<artifactId>jackson-core-asl</artifactId>

<version>1.9.7</version>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-solr</artifactId>

</dependency>

<dependency>

<groupId>org.apache.activemq</groupId>

<artifactId>artemis-server</artifactId>

</dependency>

</dependencies>

<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

</plugins>

</build>

</project>


mycss.css

.spacer {

margin-top: 20px;

}


.spacer1 {

margin-right: 20px;

}

.clickable {

cursor: pointer;

}


.width {

width: 300px;

}


.no {

width:40px;

}



myApp.js

var app=angular.module("myZitItem", []);

app.controller("myZipItemController", function($scope , $http , $log) {


$scope.zipItems=[];

$scope.zipItems1=[];

$scope.zname=null;

$scope.zname2=null;

$scope.currentPage=0;

$scope.currentPage1=0;

$scope.pageSize=30 ;

$scope.pages=[];

$scope.pages1=[];

$scope.basePath="/Demo/zipItem/list";

$scope.autoBind= false;

//getData();

// TODO Html Load시에 뿌려줄 데이터 실행.

$scope.$on = function() {

$scope.itemzName();

};

// TODO 리스트목록 가져오기 

$scope.itemzName=function() {

$http.get("/Demo/zipItem/list?page=" +  $scope.currentPage + "&size="+ $scope.pageSize )

.success(function(data) {

$scope.zipItems=data;

//$scope.pagination = data.totalPages;

$scope.number= $scope.currentPage;

$scope.totalPages=data.totalPages;

$scope.pageSize = $scope.pageSize;

$scope.pages=new Array(data.totalPages);

})

.error(function(data) {

alert('error');

});

};


// TODO 페이지 번호 클릭

$scope.goTopage=function(p) {

$scope.currentPage=p;

//$scope.itemzPaging();

$scope.itemzName();

};

// TODO 입력한 데이터 저장

$scope.chargerSave=function() {

$http({

method:'POST' ,

url :"/Demo/zipItem/save" ,

data:{"zname":$scope.zname} ,

headers:{'ontent-Type':'application/json'}

})

.success(function(data) {

$scope.$on();

})

$scope.zname='';

};

// TODO 검색 메서드

$scope.chargerSearch=function(item) {

$http({

method:'POST' ,

url : "/Demo/zipItem/search?zname=" + item + "&page="+ $scope.currentPage1 + "&size="+ $scope.pageSize ,

data: {"zname": item} ,

headers:{'ontent-Type':'application/json'}

})

.success(function(data1) {

//alert(item);

$scope.zipItems1=data1;

$scope.currentPage1=data1.currentPage;

$scope.totalPages1=data1.totalPages;

$scope.pageSize = $scope.pageSize;

$scope.pages1=new Array(data1.totalPages);

});

};

// TODO 삭제 버튼을 클릭시에 작동하는 JSON

$scope.chargerDelete=function(item ) {

//alert(item.zid);

$http({

method:'DELETE' ,

url:"/Demo/zipItem/delete/"+ item.zid

})

.success(function() {

$scope.$on();

})

.error(function() {

alert("삭제 하지 못하였습니다. !!!");

});

};

      

// TODO 검색에서 페이지 이동 버튼 클릭시 작동 메서드

$scope.chargerSearch1=function(p , p1) {

$scope.zname2 = p1;

$scope.currentPage1=p;

$scope.chargerSearch($scope.zname2 );

}

// TODO ComboBox 페이징 이동 메서드

$scope.chargerMove = function(p) {

$scope.currentPage=p;

$scope.size = $scope.pageSize;

$scope.itemzName();

};

});