728x90

댓글 테이블 생성

CREATE TABLE `main_board_reply` (
  `seq` int(11) NOT NULL AUTO_INCREMENT,
  `main_seq` int(11),
  `title` varchar(11) DEFAULT NULL,
  `name` varchar(11) DEFAULT NULL,
  `date` date DEFAULT NULL,
  `count` int(11) DEFAULT NULL,
  `content` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`seq`)
)

MainBoardReply 클래스 생성

package com.iot.db.domain;

import java.sql.Date;

import bluexmas.util.DateUtils;
import net.sf.json.JSONObject;

public class MainBoardReply {

	// pk
	private int seq;

	private int main_seq;
	private String title;
	private String name;
	private Date date;
	private int count;
	private String content;

	private String delete_flag = "N";

	public void setSeq(int seq) {
		this.seq = seq;
	}

	public int getSeq() {
		return this.seq;
	}

	public void setMain_seq(int main_seq) {
		this.main_seq = main_seq;
	}

	public int getMain_seq() {
		return this.main_seq;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getTitle() {
		return this.title;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return this.name;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	public Date getDate() {
		return this.date;
	}

	public void setCount(int count) {
		this.count = count;
	}

	public int getCount() {
		return this.count;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getContent() {
		return this.content;
	}

	public String getDelete_flag() {
		return delete_flag;
	}

	public void setDelete_flag(String delete_flag) {
		this.delete_flag = delete_flag;
	}

	public JSONObject getJSONObject() {
		JSONObject jobj = new JSONObject();
		jobj.put("seq", this.seq);
		jobj.put("main_seq", this.main_seq);
		jobj.put("title", this.title);
		jobj.put("name", this.name);
		jobj.put("date", DateUtils.datetoIsoDate(this.date));
		jobj.put("count", this.count);
		jobj.put("content", this.content);
		return jobj;
	}
}

MainBoardReplyMapper 인터페이스 생성

package com.iot.db.mapper;

import java.util.List;
import java.util.Map;

import com.iot.db.domain.MainBoardReply;

public interface MainBoardReplyMapper {

	public MainBoardReply selectMainBoardReply(Map<String, Object> params);

	public void insertMainBoardReply(MainBoardReply mainBoardReply);

	public void updateMainBoardReply(MainBoardReply mainBoardReply);

	public void deleteMainBoardReply(Map<String, Object> params);

	public int getCount();

	public int getCountFormData(Map<String, Object> params);

	public List<MainBoardReply> listMainBoardReply(Map<String, Object> map);

}

MainBoardReplyMapper.xml 생성

<?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="com.iot.db.mapper.MainBoardReplyMapper">

	<!-- selectMainBoardReply -->
	<select id="selectMainBoardReply" parameterType="map" resultType="com.iot.db.domain.MainBoardReply">
	  select seq
	         ,main_seq
	         ,title
	         ,name
	         ,date
	         ,count
	         ,content
	    from main_board_reply
	   where seq = #{seq}
	</select>
	
	<!-- updateMainBoardReply -->
	<update id="updateMainBoardReply" parameterType="com.iot.db.domain.MainBoardReply" statementType="PREPARED">
	    update main_board_reply
	      <trim prefix="SET" suffixOverrides=",">
	        <if test="main_seq != null">main_seq = #{main_seq, jdbcType=INTEGER} ,</if>
	        <if test="title != null">title = #{title, jdbcType=VARCHAR} ,</if>
	        <if test="name != null">name = #{name, jdbcType=VARCHAR} ,</if>
	        <if test="date != null">date = #{date, jdbcType=DATE} ,</if>
	        <if test="count != null">count = #{count, jdbcType=INTEGER} ,</if>
	        <if test="content != null">content = #{content, jdbcType=VARCHAR} ,</if>
	      </trim>
	   where seq = #{seq}
	</update>
	
	<!-- insertMainBoardReply -->
	<insert id="insertMainBoardReply" parameterType="com.iot.db.domain.MainBoardReply" statementType="PREPARED">
	    insert into main_board_reply(
	      <trim suffixOverrides=",">
	        <if test="main_seq != null">main_seq ,</if>
	        <if test="title != null">title ,</if>
	        <if test="name != null">name ,</if>
	        <if test="date != null">date ,</if>
	        <if test="count != null">count ,</if>
	        <if test="content != null">content ,</if>
	      </trim>
	      ) values	(
	      <trim suffixOverrides=",">
	        <if test="main_seq != null">#{main_seq, jdbcType=INTEGER} ,</if>
	        <if test="title != null">#{title, jdbcType=VARCHAR} ,</if>
	        <if test="name != null">#{name, jdbcType=VARCHAR} ,</if>
	        <if test="date != null">#{date, jdbcType=DATE} ,</if>
	        <if test="count != null">#{count, jdbcType=INTEGER} ,</if>
	        <if test="content != null">#{content, jdbcType=VARCHAR} ,</if>
	      </trim>
	      )
	</insert>
	
	<!-- deleteMainBoardReply -->
	<delete id="deleteMainBoardReply" parameterType="map" statementType="PREPARED">
	    delete from main_board_reply
	   where seq = #{seq}
	</delete>
	
	<!-- getCount -->
	<select id="getCount" resultType="int">
	  select count(*)
	    from main_board_reply
	</select>
	
	<!-- getCountFormData -->
	<select id="getCountFormData" parameterType="map" resultType="int">
	  select count(*)
	    from main_board_reply
	    <trim prefix="WHERE" prefixOverrides="AND |OR ">
	      <if test="searchstr != null">and title like '%${searchstr}%'</if>
	    </trim>
	</select>
	
	<!-- listMainBoardReply -->
	<select id="listMainBoardReply" parameterType="map" resultType="com.iot.db.domain.MainBoardReply">
	  select * 
	    from main_board_reply
	   where main_seq = #{main_seq}
	</select>

</mapper>

MainBoardReplyService 클래스 생성

package com.iot.db.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import com.iot.db.domain.MainBoardReply;
import com.iot.db.mapper.MainBoardReplyMapper;

@Service
public class MainBoardReplyService {

	public final static int pagerowcnt = 25;

	@Autowired
	private MainBoardReplyMapper mainBoardReplyMapper;

	public MainBoardReply selectMainBoardReply(int seq) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("seq", seq);
		return mainBoardReplyMapper.selectMainBoardReply(params);
	}

	public void insertMainBoardReply(MainBoardReply mainBoardReply) {
		mainBoardReplyMapper.insertMainBoardReply(mainBoardReply);
	}

	public void updateMainBoardReply(MainBoardReply mainBoardReply) {
		mainBoardReplyMapper.updateMainBoardReply(mainBoardReply);
	}

	public void deleteMainBoardReply(int seq) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("seq", seq);
		mainBoardReplyMapper.deleteMainBoardReply(params);
	}

	public void deleteMainBoardReply(Map<String, Object> params) {
		mainBoardReplyMapper.deleteMainBoardReply(params);
	}

	public int getCount() {
		return mainBoardReplyMapper.getCount();
	}

	public List<MainBoardReply> listMainBoardReply(int main_seq) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("main_seq", main_seq);
		return mainBoardReplyMapper.listMainBoardReply(params);
	}

}

댓글 입력 Form (jsp에 반영)

<form action="<c:url value="/insertReplyPage.iot"/>" method="post">
	<input type="hidden" name="main_seq" value="${seq}"/>
	<textArea name ="comment" cols="60" rows="20"></textArea>
	<input type="submit" value="답변 입력">
	<input type="button" value="취 소">
</form>

댓글 입력 처리 (컨트롤러에 반영)

	@Autowired
	MainBoardReplyService replyService;

	@RequestMapping(value = "/insertReplyPage.iot", method = RequestMethod.POST)
	public String insertReplyPage(
			@RequestParam("main_seq") int main_seq,
			@RequestParam("comment") String comment,
			ModelMap modelMap) throws Exception 
	{
		
		System.out.println("main_seq = " + main_seq + "/" + comment);
		
		MainBoardReply reply = new MainBoardReply();
		reply.setMain_seq(main_seq);
		reply.setContent(comment);
		
		replyService.insertMainBoardReply(reply);
		
		return "redirect:/moveToMainBoard.iot";
	}

게시판 도메인에 댓글 목록 추가

	private List<MainBoardReply> replyList;
	
	public List<MainBoardReply> getReplyList() {
		return replyList;
	}
	public void setReplyList(List<MainBoardReply> replyList) {
		this.replyList = replyList;
	}

게시판 리스트 (컨트롤러에 반영)

	@RequestMapping(value = "/moveToMainBoard.iot", method = RequestMethod.GET)
	public String moveToMainBoard(ModelMap modelMap) throws Exception {
		
		// 게시판 내용 조회
		List<main_boardDto> main_boardDtoList = service.selectMainBoardList();
		
		// 댓글 조회
		for (main_boardDto board: main_boardDtoList) {
			List<MainBoardReply> replyList = replyService.listMainBoardReply(board.getSeq());
			board.setReplyList(replyList);
		}
		
		System.out.println("main_baordDto : " +main_boardDtoList);
		modelMap.addAttribute("main_boardDto",main_boardDtoList);
		return "/main_board";
	}

게시판 리스트 (jsp에 반영)

  <c:forEach items="${main_boardDto}" var="data" varStatus="loop">
  	<tr>
  		<td><input type="checkbox" name="delete_seqs" value="${data.seq}"/></td>
  		<td>${data.seq}</td>
  		<td class="underline" onclick="javascript:readContent(${data.seq});">${data.title}</td>
  		<td onclick="javascript:modifyExplanation_content(${data.seq});">${data.name}</td>
  		<td>${data.date}</td>
  		<td>${data.count}</td>
    </tr>
    <c:forEach items="${data.replyList}" var="reply" varStatus="loop">
  	  <tr>
  		<td><input type="checkbox" name="delete_seqs" value="${reply.seq}"/></td>
  		<td>${reply.seq}</td>
  		<td>  -> ${reply.content}</td>
  		<td>${reply.name}</td>
  		<td>${reply.date}</td>
  		<td>${reply.count}</td>
      </tr>
    </c:forEach>
  </c:forEach>
728x90
728x90

출처 : IT 조각 모음: [java] spring3 + tiles3 설정 하기

iot-servlet.xml 내용추가(WebContent\WEB-INF\iot-servlet.xmll)

	<!-- 타일즈 설정 : 시작 -->
	<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
		<property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView" />
		<property name="order" value="1"/>
	</bean>
	<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
		<property name="definitions">
 			<list>
				<value>/WEB-INF/tiles/tiles-layout.xml</value>
			</list>
		</property>
 	</bean>
 	<!-- 타일즈 설정 : 종료 -->

타일즈 환경설정 파일 생성(WebContent\WEB-INF\tiles\tiles-layout.xmll)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC 
	"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" 
	"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">	

<tiles-definitions>
	
	<definition name="/*.blank" template="/WEB-INF/tiles/blankLayout.jsp">
		<put-attribute name="content"	value="/WEB-INF/jsp/{1}.jsp"/>
	</definition>
	
	<definition name="/*" template="/WEB-INF/tiles/web_layout.jsp">
		<put-attribute name="header" value="/WEB-INF/tiles/web_header.jsp" />
		<put-attribute name="main" value="/WEB-INF/jsp/{1}.jsp" />
		<put-attribute name="footer" value="/WEB-INF/tiles/web_footer.jsp" />	
	</definition>
	
</tiles-definitions>

레이아웃(web_layout.jsp) 파일 생성(WebContent\WEB-INF\tiles\web_layout.jsp)

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0 minimal-ui"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black">
</head>

<body>

<div id="wrap">
	<!-- head -->
	<div id="header"><tiles:insertAttribute name="header" /></div>
	
	<!-- content -->
	<div id="body">
		<div id="container"><tiles:insertAttribute name="main" /></div>
	</div>

	<!-- footer -->
	<div id="footer"><tiles:insertAttribute name="footer" /></div>
</div>
	
</body>
</html>

상당 페이지(web_header.jsp) 파일 생성(WebContent\WEB-INF\tiles\web_header.jsp)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>

<div>
로그인사용자 : <sec:authentication property="principal.username" />
</div>

<div>
	<a href="<c:url value="/j_spring_security_logout"/>">로그아웃</a> 
	<a href="<c:url value="/user_add_ajax.iot"/>">회원 가입</a>
</div>

하단 페이지(web_footer.jsp) 파일 생성(WebContent\WEB-INF\tiles\web_footer.jsp)

<%@ page contentType="text/html;charset=utf-8"%>

<div>
회사이름 : 파란크리스마스
</div>

실행결과

footer 하단영역에 고정시키기 (WebContent\WEB-INF\tiles\web_layout.jsp 내용추가)

출처 : footer 하단영역에 고정시키기 | 신기한 웹 세상

<style>
html, body { margin:0; padding:0; height:100%; }
#wrap {
    height:100%;
}
#header {
    position:relative;
    width:100%;
    height:45px;
    background-color:#eaeaea;
}
#body {
    margin:-45px 0 -50px;
    width:100%;
    min-height:100%;
}
#body #container {
    padding:45px 0 50px;
}
 
#footer {
    width:100%;
    height:50px;
    background-color:#eaeaea;
}
</style>

스타일 적용 실행결과

상하단 페이지가 필요없는 경우 처리(WebContent\WEB-INF\tiles\blankLayout.jsp 생성)

<jsp:directive.page import="org.springframework.web.context.request.RequestAttributes"/>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles"%>
<tiles:insertAttribute name="content"/>

로그인 페이지 blankLayout 사용(src\com\iot\controller\LoginController.java 내용수정)

return "/login"; 에서 return "/login.blank"; 로 수정

	@RequestMapping(value = "/login.iot", method = RequestMethod.GET)
	public String login(ModelMap modelMap) throws Exception {
		return "/login.blank";
	}

blankLayout 적용 전후

  

728x90
728x90

Spring Security

출처 : 사랑이 고픈 프로그래머.. - 흔히 보게되는 절대 써먹을 수 없는 Spring Security의 초간단 셋팅
jjeong :: Spring Security login/logout 관련 글

web.xml 내용추가(WebContent\WEB-INF\web.xml)

	<!-- 스프링 스큐리티 관련 설정 / 시작 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/iot-datasource.xml
			/WEB-INF/iot-mybatis.xml
			/WEB-INF/iot-security.xml
		</param-value>
	</context-param>
	
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	
	<filter>
		<filter-name>springSecurityFilterChain</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>springSecurityFilterChain</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!-- 스프링 스큐리티 관련 설정 / 끝 -->

iot-security.xml 파일 생성(WebContent\WEB-INF\iot-security.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:security="http://www.springframework.org/schema/security"
	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.2.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security-3.2.xsd">

	<!-- 확장자를 이용해 패턴을 걸때는 /**/*.해당 확장자 로 할 것(Ant Pattern 규칙) -->
	<security:http pattern="/**/*.js" security="none"/>
	<security:http pattern="/**/*.css" security="none"/>
	<security:http pattern="/images/*" security="none"/>
	
	<!--
	<security:http pattern="/user_add_ajax.iot" security="none" //>
	<security:http pattern="/login.iot" security="none" />
	<security:http pattern="/loginfailed.iot" security="none" />
	<security:http pattern="/logout.iot" security="none" />
	-->
	
	<security:http auto-config="true">
		<security:intercept-url pattern="/json.iot" access="ROLE_ANONYMOUS,ROLE_USER" />
		<security:intercept-url pattern="/**/*.iot" access="ROLE_USER"/>
		
		<!-- 
		<security:form-login login-page="/login.iot" default-target-url="/hello_world.iot" authentication-failure-url="/loginfailed.iot" />
		<security:logout logout-success-url="/login.iot" />
		-->
	</security:http>

	<security:authentication-manager>
		<security:authentication-provider>

			<security:jdbc-user-service
				data-source-ref="dataSource"
				users-by-username-query="select user_id username, password password, 1 as enabled from user_info where user_id = ?"
				authorities-by-username-query="select name username, 'ROLE_USER' authority from user_info where user_id = ?" />

		</security:authentication-provider>
	</security:authentication-manager>

</beans>

로그인 페이지 만들기

package com.iot.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class LoginController {

	@RequestMapping(value = "/login.iot", method = RequestMethod.GET)
	public String login(ModelMap modelMap) throws Exception {
		return "/login";
	}
}

로그인페이지 추가 (WebContent\WEB-INF\jsp\login.jsp)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Login Page</title>
<style>
.errorblock {
	color: #ff0000;
	background-color: #ffEEEE;
	border: 3px solid #ff0000;
	padding: 8px;
	margin: 16px;
}
</style>
</head>
<body onload='document.f.j_username.focus();'>

 <div id="background_login">
	<h3>IOT 로그인 페이지</h3>
 
	<c:if test="${not empty error}">
		<div class="errorblock">
			Your login attempt was not successful, try again.<br /> Caused :
			${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message}
		</div>
	</c:if>

	<form name='f' action="<c:url value='j_spring_security_check' />" method='POST'>
		<table>
			<tr>
				<td>사용자ID : </td>
				<td><input type='text' name='j_username' value=''>
				</td>
			</tr>
			<tr>
				<td>PassWord : </td>
				<td><input type='password' name='j_password' />
				</td>
			</tr>
			<tr>
				<td><input name="submit" type="submit" value="로그인" />
				<td><input name="reset" type="reset" />
				</td>
			</tr>
		</table>
	</form>
</div>

<a href="<c:url value='/user_add_ajax.iot' />">사용자추가</a>

</body>
</html>

시큐리티 제외 주소 설정

iot-security.xml 파일 내용 추가(WebContent\WEB-INF\iot-security.xml)

로그인 관련 주소는 시큐리티 설정에서 제외 시킨다.

	<security:http pattern="/user_add_ajax.iot" security="none" />
	<security:http pattern="/login.iot" security="none" />
	<security:http pattern="/loginfailed.iot" security="none" />
	<security:http pattern="/logout.iot" security="none" />

로그인 페이지 설정

iot-security.xml 파일 내용 추가(WebContent\WEB-INF\iot-security.xml)

		<security:form-login login-page="/login.iot" 
			default-target-url="/hello_world.iot" 
			authentication-failure-url="/loginfailed.iot" />
		<security:logout logout-success-url="/logout.iot" />

로그아웃

웹페이지 주소에 /j_spring_security_logout 이동하면 로그아웃

로그인 아웃 페이지 만들기(src\com\iot\controller\LoginController.java)

	@RequestMapping(value = "/logout.iot", method = RequestMethod.GET)
	public String logout(ModelMap modelMap) throws Exception {
		return "/logout";
	}

로그인아웃 페이지 추가 (WebContent\WEB-INF\jsp\logout.jsp)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Login Page</title>
</head>
<body>
	<h3>로그아웃</h3>	
	<a href="<c:url value="j_spring_security_logout" />" >로그아웃</a>
</body>
</html>

컨트롤러에서 로그인 아이디 얻기

	Authentication auth = SecurityContextHolder.getContext().getAuthentication();
	String user_id = auth.getName();


728x90
728x90

삭제 CheckBox 추가(hello_world.jsp)

hello_world.jsp에서 목록을 form으로 감싸고, 사용자 마다 삭제 checkbox를 추가

<h1>사용자 조회</h1>
<form action="delete_user.iot" method="post">
	<table border="1">
		<c:forEach items="${userlist}" var="data" varStatus="loop">
			<tr>
				<td><input type="checkbox" name="delete_user_ids" value="${data.user_id}"/></td>
				<td><a href="<c:url value="/edit_user.iot"/>?user_id=${data.user_id}">${data.user_id}</a></td>
				<td>${data.password}</td>
				<td>${data.name}</td>
				<td>${data.nickname}</td>
			</tr>
		</c:forEach>
	</table>
	<br/>
	<input type="submit" value="삭제"/>
</form>

src\com\iot\controller\UserController.java 클래스 내용 추가

	@RequestMapping(value = "/delete_user.iot", method = RequestMethod.POST)
	public String delete_user(@RequestParam("delete_user_ids") String[] delete_user_ids, ModelMap modelMap) throws Exception {
		// 삭제할 사용자 ID마다 반복해서 사용자 삭제
		for (String user_id : delete_user_ids) {
			System.out.println("사용자 삭제 = " + user_id);
			int delete_count = service.deleteUser(user_id);
		}
		// 목록 페이지로 이동
		return "redirect:/hello_world.iot";
	}

src\com\iot\db\service\UserInfoService.java 클래스 내용 추가

	public int deleteUser(String user_id) {
		return userInfoMapper.deleteUser(user_id);
	}

src\com\iot\db\mapper\UserInfoMapper.java 인터페이스 내용 추가

	public int deleteUser(String user_id);

src\com\iot\db\mapper\UserInfoMapper.xml 내용 추가

	<!-- deleteUser -->
	<delete id="deleteUser" parameterType="java.lang.String" statementType="PREPARED">
		delete from user_info where user_id = #{user_id}
	</delete>
728x90
728x90

수정페이지 이동(hello_world.jsp)

hello_world.jsp에서 사용자 아이디에 수정페이지로 이동하도록 내용 추가

<td><a href="<c:url value="/edit_user.iot"/>?user_id=${data.user_id}">${data.user_id}</a></td>

src\com\iot\controller\UserController.java 클래스 내용 추가

	@Autowired
	private UserInfoService service;

	@RequestMapping(value = "/edit_user.iot", method = RequestMethod.GET)
	public String edit_user(@RequestParam("user_id") String user_id, ModelMap modelMap) throws Exception {
		
		UserInfo userinfo = service.selectUser(user_id);
		
		// 사용자 수정용 객체 설정
		modelMap.addAttribute("userinfo", userinfo);
		
		return "/edit_user";
	}
	
	@RequestMapping(value = "/edit_user_apply.iot", method = RequestMethod.POST)
	public String edit_user_apply(UserInfo userinfo, ModelMap modelMap) throws Exception {
		int updateCount = service.updatetUser(userinfo);
		return "redirect:/hello_world.iot";
	}

src\com\iot\db\service\UserInfoService.java 클래스 내용 추가

	public UserInfo selectUser(String user_id) {
		return userInfoMapper.selectUser(user_id);
	}

	public int updatetUser(UserInfo userinfo) {
		return userInfoMapper.updatetUser(userinfo);
	}

src\com\iot\db\mapper\UserInfoMapper.java 인터페이스 내용 추가

	public UserInfo selectUser(String user_id);

	public int updatetUser(UserInfo userinfo);

src\com\iot\db\mapper\UserInfoMapper.xml 내용 추가

	<!-- selectUser -->
	<select id="selectUser" parameterType="java.lang.String" resultType="com.iot.db.domain.UserInfo">
		select *
		  from user_info
		 where user_id = #{user_id}
	</select>
	
	<!-- updatetUser -->
	<update id="updatetUser" parameterType="com.iot.db.domain.UserInfo" statementType="PREPARED">
		update user_info
		<trim prefix="SET" suffixOverrides=",">
			<if test="password != null">password = #{password, jdbcType=VARCHAR} ,</if>
			<if test="name != null">name = #{name, jdbcType=VARCHAR} ,</if>
			<if test="nickname != null">nickname = #{nickname, jdbcType=VARCHAR} ,</if>
		</trim>
		 where user_id = #{user_id}
	</update>

WebContent\WEB-INF\jsp\edit_user.jsp 파일 생성

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

<!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>

<h1>사용자 수정</h1>
<form:form id="dataForm" name="dataForm" modelAttribute="userinfo" action="edit_user_apply.iot" method="post">
	<form:hidden path="user_id"/>
	<table border="1">
		<tr>
			<td>사용자ID</td>
			<td>
				${userinfo.user_id}
			</td>
		</tr>
		<tr>
			<td>암호</td>
			<td>
				<form:input path="password"/>
			</td>
		</tr>
		<tr>
			<td>사용자이름</td>
			<td>
				<form:input path="name"/>
			</td>
		</tr>
		<tr>
			<td>별명</td>
			<td>
				<form:input path="nickname"/>
			</td>
		</tr>
	</table>
	<br/>
	<input type="submit" value="사용자 수정"/>
</form:form>

</body>
</html>
728x90
728x90

JSONData 추상 클래스 생성

Factory 패턴에서 반환 가능한 형태로 만들기 위해서 추상 클래스를 사용하기때문에 아래와 같이 추상 클래스를 생성

package com.iot.json;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

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

import net.sf.json.JSONObject;

public abstract class JSONData {
	
	private static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
	
	public abstract JSONObject getJSON(HttpServletRequest request, HttpServletResponse response);
	
	public JSONObject getJSONObject(Map<String, Object> map) {
		JSONObject jobj = new JSONObject();
		//loop a Map
		for (Map.Entry<String, Object> entry : map.entrySet()) {
			if (entry.getValue() instanceof java.sql.Date) {
				//
				jobj.put(entry.getKey(), fromCalendar((Date) entry.getValue()));
			} else {
				jobj.put(entry.getKey(), entry.getValue());
			}
		}
		return jobj;
	}
	
	public static String fromCalendar(final Date date) {
		String formatted = formatter.format(date);
		return formatted.substring(0, 22) + ":" + formatted.substring(22);
	}
}

JSONSample 클래스 생성

간단하게 테스트나 이해를 돕기 위해서 JSONData 추상 클래스를 상속받아서 Sample 클래스를 생성

package com.iot.json;

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

import org.springframework.stereotype.Controller;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

@Controller
public class JSONSample extends JSONData {

	@Override
	public JSONObject getJSON(HttpServletRequest request, HttpServletResponse response) {
		JSONArray arrayObj = new JSONArray();
		
		JSONArray data = new JSONArray();
		data.add("Tiger Nixon");
		data.add("System Architect");
		data.add("Edinburgh");
		data.add("5421");
		data.add("2011/04/25");
		data.add("$320,800");
		arrayObj.add(data);
		
		data = new JSONArray();
		data.add("Garrett Winters");
		data.add("Accountant");
		data.add("Tokyo");
		data.add("8422");
		data.add("2011/07/25");
		data.add("$170,750");
		arrayObj.add(data);
		
		JSONObject jobj_data = new JSONObject();
		jobj_data.put("data", arrayObj);
		
		return jobj_data;
	}
}

JSONFactory 클래스 생성

Factory 패턴으로 cmd 값에 따라 해당 JSONData를 구현한 객체를 반환

package com.iot.json;

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

@Controller
public class JSONFactory {
	
	@Autowired
	private JSONSample jSONSample;
	
	public JSONData getJSONData(String cmd) {
		
		System.out.println("cmd = " + cmd);
		
		if (true) {
			return jSONSample;
		}
		
		return jSONSample;
	}
}

JSONController 클래스 생성

json 형태로 데이터 반환

package com.iot.json;

import java.io.IOException;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class JSONController {
	
	@Autowired
	private JSONFactory jSONFactory;

	@ResponseBody
	@RequestMapping(value="/json.iot", method=RequestMethod.GET, produces="application/json; charset=utf-8")
	public String service(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) throws IOException {
		
		/*
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		String reg_id = auth.getName();
		*/
		
		/*
		Enumeration<String> keys = request.getParameterNames();
		while(keys.hasMoreElements()) {
			String key = keys.nextElement();
			System.out.println("param = " + key + "/" + request.getParameter(key));
		}
		*/
		
		String cmd = request.getParameter("cmd");
		if (cmd==null) {
			cmd = "";
		}
		
		JSONData json = jSONFactory.getJSONData(cmd);
		
		return json.getJSON(request, response).toString();
	}

}

iot-servlet.xml 내용 추가

json 관련 패키지가 자동으로 스프링컨테이너에 로딩 되도록 WEB-INF/iot-servlet.xml 파일에에 아래 내용을 추가

<context:component-scan base-package="com.iot.json"/>

	<!-- 컨트롤더 package 자동으로 스프링 컨테이너 등록 -->
	<context:component-scan base-package="com.iot.controller"/>
	<context:component-scan base-package="com.iot.json"/>

Sample 데이터 확인

JSONUser 클래스 추가

AJAX로 사용자 추가하는 클래스를 만들기 위해서  JSONData 추상 클래스를 상속받아서 JSONUser 클래스를 생성

package com.iot.json;

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

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

import com.iot.db.domain.UserInfo;
import com.iot.db.service.UserInfoService;

import net.sf.json.JSONObject;

@Controller
public class JSONUser extends JSONData {
	
	public static String COMMAND = "user";
	
	@Autowired
	private UserInfoService service;

	@Override
	public JSONObject getJSON(HttpServletRequest request, HttpServletResponse response) {
		String subcmd = request.getParameter("subcmd");
		System.out.println("subcmd = " + subcmd);	
		
		JSONObject jobj_data = null;
		if (subcmd.equals("add")) {
			jobj_data = getAddData(request, response);
		}
			
		return jobj_data;
	}

	private JSONObject getAddData(HttpServletRequest request, HttpServletResponse response) {
		
		String errStr = null;
		
		try {
			UserInfo userinfo = new UserInfo();
			userinfo.setUser_id(request.getParameter("user_id"));
			userinfo.setPassword(request.getParameter("password"));
			userinfo.setName(request.getParameter("name"));
			userinfo.setNickname(request.getParameter("nickname"));
			
			service.insertUserInfo(userinfo);
		} catch (Exception e) {
			errStr = e.toString();
			e.printStackTrace();
		}
		
		JSONObject jobj_data = new JSONObject();
		jobj_data.put("success", (errStr == null ? true : false));
		
		return jobj_data;
	}

}

JSONFactory 수정

파라미터 cmd의 값이 user인 경우 JSONUser의 객체가 반환 되도록 코드 추가

package com.iot.json;

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

@Controller
public class JSONFactory {
	
	@Autowired
	private JSONUser jSONUser;
	
	@Autowired
	private JSONSample jSONSample;
	
	public JSONData getJSONData(String cmd) {
		
		System.out.println("cmd = " + cmd);
		
		if (JSONUser.COMMAND.equals(cmd)) { // JSONUser.COMMAND = user
			return jSONUser;
		} else {
			return jSONSample;
		}
		
		// return jSONSample;
	}
}

UserController 클래스 생성

사용자 관련 Controller 클래스 생성

package com.iot.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class UserController {
	
	@RequestMapping(value = "/user_add_ajax.iot", method = RequestMethod.GET)
	public String user_add_ajax(ModelMap modelMap) throws Exception {
		return "/user_add_ajax";
	}

}

user_add_ajax.jsp 생성

사용자 추가 JSP 작성 - JQuery AJAX 통신

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<!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">
<script  src="http://code.jquery.com/jquery-latest.min.js"></script>
<title>사용자추가</title>
<script type="text/javascript">
function user_add() {
	var form = document.uploadForm;
    //var form = new FormData(document.getElementById('uploadForm'));
	$.ajax({
	  url: "<c:url value="/json.iot"/>",
	  data: {
		cmd : "user",
		subcmd : "add",
		user_id : form.user_id.value,
		password : form.password.value,
		name : form.name.value,
		nickname : form.nickname.value
	  },
	  // data: form,
	  dataType: 'json',
	  contentType: false,
	  type: 'GET',
	  success: function (response) {
	    console.log('success');
	    console.log(response);
	  },
	  error: function (jqXHR) {
	    console.log('error');
	  }
	});
}
</script>
</head>
<body>

<h1>사용자 추가</h1>
<form id="uploadForm" name="uploadForm" method="get">
	<input type="hidden" name="cmd" value="user">
	<input type="hidden" name="subcmd" value="add">
	<table border="1">
		<tr>
			<td>사용자ID</td>
			<td>
				<input type="text" name="user_id"/>
			</td>
		</tr>
		<tr>
			<td>암호</td>
			<td>
				<input type="text" name="password"/>
			</td>
		</tr>
		<tr>
			<td>사용자이름</td>
			<td>
				<input type="text" name="name"/>
			</td>
		</tr>
		<tr>
			<td>별명</td>
			<td>
				<input type="text" name="nickname"/>
			</td>
		</tr>
		<!-- 
		<tr>
			<td>사진</td>
			<td>
				<input type="file" name="photo"/>
			</td>
		</tr>
		-->
	</table>
	<br/>
	<input type="button" value="사용자추가" onclick="javascript:user_add();"/>
</form>

</body>
</html>


728x90
728x90

Spring MVC - JSTL Form radio 버튼

출처 : Spring MVC radiobutton and radiobuttons example

코드 객체 생성

package com.iot.db.domain;

public class CodeString {

	private String code;

	private String title;

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

}

jsp

<form:select path="breed">
	<form:options items="${allBreeds}" itemValue="code" itemLabel="title" />
</form:select>

select option

<select id="cmb_code_type" style="height:35px" onchange="javascript:listCode(1);">
	<c:forEach var="code" items="${list_code_type}" varStatus="status">
		<option value="<c:out value="${code.id}"/>" index="${status.index}">
			<c:out value="${code.title}"/>
		</option>
	</c:forEach>
</select>
728x90
728x90

Spring MVC Multipart Configuration (iot-servlet.xml 내용추가)

출처 : Spring MVC File Upload Example Tutorial - Spring MVC File Upload Example Tutorial – Single and Multiple Files
스프링(Spring) 파일 업로드(File Upload) :: 갱짱.study - 이갱짱 - Tistory

	<!-- ========================= Multipart Form-Data Resolver ========================= -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!--
		<property name="maxUploadSize">
			<value>10000000</value>
		</property>
		-->
	</bean>

FileUploadController.java

package com.iot.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
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.multipart.MultipartFile;

@Controller
public class FileUploadController {

	@RequestMapping(value = "/file_upload_form.iot", method = RequestMethod.GET)
	public String file_upload_form(ModelMap modelMap) {
		return "/file_upload_form";
	}
	
	@RequestMapping(value = "/file_upload_save.iot", method = RequestMethod.POST)
	public String file_upload_save(@RequestParam("uploadfile") MultipartFile uploadfile, ModelMap modelMap) {

		OutputStream out = null;
		PrintWriter printWriter = null;

		try {
			// 파일명 얻기
			String fileName = uploadfile.getOriginalFilename();
			// 파일의 바이트 정보 얻기
			byte[] bytes = uploadfile.getBytes();
			// 파일의 저장 경로 얻기
			String uploadPath = getDestinationLocation() + fileName;
			
			// 파일 객체 생성
			File file = new File(uploadPath);
			// 상위 폴더 존재 여부 확인
			if (!file.getParentFile().exists()) {
				// 상위 폴더가 존재 하지 않는 경우 상위 폴더 생성
				file.getParentFile().mkdirs();
			}
			
			// 파일 아웃풋 스트림 생성
			out = new FileOutputStream(file);
			// 파일 아웃풋 스트림에 파일의 바이트 쓰기
			out.write(bytes);
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null) {
					out.close();
				}
				if (printWriter != null) {
					printWriter.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return "/file_upload_form";
	}
	
	private String getDestinationLocation() {
		return "/업로드폴더/";
	}
}

file_upload_form.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="file_upload_save.iot" method="post" enctype="multipart/form-data">
		<fieldset>
			<table>
				<tr>
					<th>파일</th>
					<td><input type="file" name="uploadfile" required="required"></td>
				</tr>
				<tr>
					<td colspan="2">
						<input type="submit" value="작성">
						<input type="reset" value="취소">
					</td>
				</tr>
			</table>
		</fieldset>
	</form>
</body>
</html>

업로드 폴더 웹에 노출시키기

{tomcat_home}/conf/server.xml 내용 추가

<Context docBase="C:/업로드폴더" path="uploaddir" reloadable="true"/>

JQuery Ajax로 파일 업로드

출처 - Programming is Fun :: Spring MVC를 이용한 Ajax File upload

FileUploadController 내용 추가

	@RequestMapping(value = "/file_upload_form_ajax.iot", method = RequestMethod.GET)
	public String file_upload_form_ajax(ModelMap modelMap) {
		return "/file_upload_form_ajax";
	}

	@ResponseBody
	@RequestMapping(value = "/file_upload_save_ajax.iot", headers="Accept=*/*", method = RequestMethod.POST)
	public String file_upload_save_ajax(@RequestParam("uploadfile") MultipartFile uploadfile, ModelMap modelMap) {

		OutputStream out = null;

		try {
			String fileName = uploadfile.getOriginalFilename();
			byte[] bytes = uploadfile.getBytes();
			String uploadPath = getDestinationLocation() + fileName;// 저장경로
			
			File file = new File(uploadPath);
			if (!file.getParentFile().exists()) {
				file.getParentFile().mkdirs();
			}
			
			out = new FileOutputStream(file);
			out.write(bytes);
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null) {
					out.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return "true";
	}

file_upload_form_ajax.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script  src="http://code.jquery.com/jquery-latest.min.js"></script>
<title>Insert title here</title>
<script type="text/javascript">
$( document ).ready(function() {
  $('#btn-upload').on('click', function () {
    console.log('btn-upload');
    var form = new FormData(document.getElementById('uploadForm'));
    $.ajax({
      url: "file_upload_save_ajax.iot",
      data: form,
      dataType: 'text',
      processData: false,
      contentType: false,
      type: 'POST',
      success: function (response) {
        console.log('success');
        console.log(response);
      },
      error: function (jqXHR) {
        console.log('error');
      }
    });
  });
});
</script>
</head>
<body>
	<form action="file_upload_save.iot" method="POST" id="uploadForm" enctype="multipart/form-data">
		<fieldset>
			<table>
				<tr>
					<th>파일</th>
					<td><input type="file" name="uploadfile" required="required"></td>
				</tr>
				<tr>
					<td colspan="2">
						<input type="submit" value="작성">
						<input type="reset" value="취소">
					</td>
				</tr>
			</table>
		</fieldset>
	</form>
	<span id="btn-upload">파일업로드AJAX</span>
</body>
</html>


728x90

+ Recent posts