반응형
📝모자이크
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<html>
<head>
<title>Mosaic Captcha</title>
<!-- CSS -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
crossorigin="anonymous">
<!-- JS -->
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div class="row justify-content-center">
<div class="col-2"></div>
<div class="col-8">
<!-- 문제 -->
<div class="row justify-content-center text-center">
<div class="col-2"></div>
<div class="col-8">
<img src='/captcha/mosaic/question' width="500px" height="500px" />
<div class="my-3">
<b>검은 칸에 해당하는 사진 번호를 입력해주세요</b>
</div>
</div>
<div class="col-2"></div>
</div>
<!-- 객관식 리스트 -->
<div class="row text-center">
<div class="col">
<img src='/captcha/mosaic/multiple/choice' />
</div>
</div>
<!-- 정답란 -->
<div class="row mt-3">
<div class="col-2"></div>
<div class="col-8">
<div class="row">
<input class="form-control my-1" type="text" id="userAnswer"
placeholder="정답번호를 입력해주세요">
</div>
</div>
<div class="col-2"></div>
</div>
<!-- 제출 -->
<div class="row mt-3">
<div class="col-2"></div>
<div class="col-8">
<div class="row">
<button class="btn btn-primary" onClick="showResult()">제출</button>
</div>
</div>
<div class="col-2"></div>
</div>
</div>
<div class="col-2"></div>
</div>
<script
src="<%=request.getContextPath()%>/resources/js/captcha/captcha_mosaic.js"></script>
</body>
</html>
View
let checkAnswer = async () => {
let userAnswer = document.getElementById('userAnswer').value
let response = await
fetch("/captcha/mosaic/answer?userAnswer=" + userAnswer, {
method: "GET",
});
return response.json();
}
let showResult = () => {
checkAnswer().then((result) => {
if(result.response === "right") alert("정답입니다");
else if(result.response === "wrong") alert("오답입니다");
});
}
$("#userAnswer").keydown(function(key) {
if (key.keyCode == 13) {
showResult();
}
});
JavaScript
package com.lsj.study.controller;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.lsj.study.util.MosaicCaptcha;
@Controller
public class CaptchaController {
/** ------------ Mosaic CaptCha Page ------------ **/
@GetMapping(value = "/captcha/mosaic")
public String captchaMosaic(HttpServletRequest reques) {
/** Referer 필요시 사용 **/
// String referer = request.getHeader("Referer");
//
// if (referer.equals(rightReferer)) return "captcha/captcha_mosaic";
// else return "captcha/wrong_page";
return "captcha/captcha_mosaic";
}
/** ------------ Mosaic CaptCha Multiple Choice (객관식 그림) ------------ **/
@GetMapping(value = "/captcha/mosaic/multiple/choice")
public void getQuestionList(HttpServletResponse response, HttpSession session) throws IOException {
MosaicCaptcha mosaicCaptcha = new MosaicCaptcha();
/** 객관식 번호 가져오기 **/
BufferedImage choiceNum1 = mosaicCaptcha.getMosaicQuestionImage(session);
BufferedImage choiceNum2 = mosaicCaptcha.getMosaicQuestionImage(session);
BufferedImage choiceNum3 = mosaicCaptcha.getMosaicQuestionImage(session);
BufferedImage choiceNum4 = mosaicCaptcha.getMosaicAnswerImage(session);
/** 화면 준비 **/
OutputStream out = response.getOutputStream();
/** 객관식 정보 담기 **/
Map<String, BufferedImage> multipleChoiceMap = new HashMap<String, BufferedImage>();
multipleChoiceMap.put("wrong1", choiceNum1);
multipleChoiceMap.put("wrong2", choiceNum2);
multipleChoiceMap.put("wrong3", choiceNum3);
multipleChoiceMap.put("answer", choiceNum4);
/** 객관식 번호 섞기 **/
List<String> keys = new ArrayList(multipleChoiceMap.keySet());
Collections.shuffle(keys);
/** 객관식 번호 부여하기 **/
BufferedImage questionNum1 = mosaicCaptcha.drawNumberOnMultipleChoiceImage("1");
BufferedImage questionNum2 = mosaicCaptcha.drawNumberOnMultipleChoiceImage("2");
BufferedImage questionNum3 = mosaicCaptcha.drawNumberOnMultipleChoiceImage("3");
BufferedImage questionNum4 = mosaicCaptcha.drawNumberOnMultipleChoiceImage("4");
/** key로 정답을 찾아 session 영역에 저장 **/
int answerNum = keys.indexOf("answer");
session.setAttribute("mosaicAnswer", answerNum + 1);
System.out.println("Mosaic-answer : " + (answerNum + 1));
/** 객관식 리스트 합쳐 하나의 이미지로 재구성 **/
try {
/** 기본 바탕화면 구성 **/
BufferedImage mergedImage = new BufferedImage(550, 100, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = (Graphics2D) mergedImage.getGraphics();
graphics.setPaint(new Color(255, 255, 255));
graphics.fillRect(0, 0, mergedImage.getWidth(), mergedImage.getHeight());
/** 객관식 리스트 **/
graphics.drawImage(multipleChoiceMap.get(keys.get(0)), 0, 0, null);
graphics.drawImage(multipleChoiceMap.get(keys.get(1)), 150, 0, null);
graphics.drawImage(multipleChoiceMap.get(keys.get(2)), 300, 0, null);
graphics.drawImage(multipleChoiceMap.get(keys.get(3)), 450, 0, null);
/** 객관식 리스트의 번호 부여 **/
graphics.drawImage(questionNum1, 10, 0, null);
graphics.drawImage(questionNum2, 160, 0, null);
graphics.drawImage(questionNum3, 310, 0, null);
graphics.drawImage(questionNum4, 460, 0, null);
/** 화면에 출력 **/
response.setContentType("image/png");
ImageIO.write(mergedImage, "png", out);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
/** ------------ Mosaic CaptCha Question (문제) ------------ **/
@GetMapping(value = "/captcha/mosaic/question")
public void getMosaicQuestion(HttpServletResponse response, HttpSession session)
throws IOException {
MosaicCaptcha mosaic = new MosaicCaptcha();
/** 랜덤 이미지 받기 **/
String fileImagePath = mosaic.getRandomMosaicImage(session);
/** 자를 부분 랜덤 XY 좌표 설정 **/
mosaic.setCutXYPoint(session);
File file = new File(fileImagePath); // 리사이즈할 파일 정보
int resizedWidth = 500; // 리사이즈할 가로 길이
int resizedHeight = 500; // 리사이즈할 세로 길이
/** 리사이징 **/
BufferedImage blackBoxImage = mosaic.resize(file, resizedWidth, resizedHeight);
/** 문제 낼 곳에 블랙박스 생성 **/
int blackBoxWidth = 100;
int blackBoxHeight = 100;
mosaic.drawBlackBox(blackBoxImage, blackBoxWidth, blackBoxHeight, session);
/** 화면에 뿌릴 준비 **/
OutputStream out = response.getOutputStream();
/** 화면에 뿌리기 **/
response.setContentType("image/png");
ImageIO.write(blackBoxImage, "png", out);
}
/** ------------ Mosaic CaptCha Confirm (정답 확인) ------------ **/
@GetMapping(value = "/captcha/mosaic/answer")
public @ResponseBody Map<Object, Object> confirmCaptChaMosaic(HttpServletRequest request, HttpSession session) {
Map<Object, Object> result = new HashMap<>();
/** 정답 가져오기 **/
session = request.getSession();
String answer = String.valueOf((int) session.getAttribute("mosaicAnswer")); // 정답
String userAnswer = request.getParameter("userAnswer"); // 유저 정답
System.out.println("Mosaic-userAnswer : " + userAnswer);
/** 정답 확인 **/
if (userAnswer.equals(answer)) result.put("response", "right");
else result.put("response", "wrong");
return result;
}
}
Controller
package com.lsj.study.util;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpSession;
import org.springframework.core.io.ClassPathResource;
import com.lsj.study.vo.ImageVo;
public class MosaicCaptcha {
/**
* @param session : 사용자 session
* @return 랜덤 모자이크에 사용할 이미지 가져오기
*/
public String getRandomMosaicImage(HttpSession session) {
int randomImage = (int) (Math.random() * 6) + 1;
String filePath = "";
switch (randomImage) {
case 1:
filePath = new ClassPathResource("image/captcha/mosaic/mosaic_1.png").getPath();
break;
case 2:
filePath = new ClassPathResource("image/captcha/mosaic/mosaic_2.png").getPath();
break;
case 3:
filePath = new ClassPathResource("image/captcha/mosaic/mosaic_3.png").getPath();
break;
case 4:
filePath = new ClassPathResource("image/captcha/mosaic/mosaic_4.png").getPath();
break;
case 5:
filePath = new ClassPathResource("image/captcha/mosaic/mosaic_5.png").getPath();
break;
case 6:
filePath = new ClassPathResource("image/captcha/mosaic/mosaic_6.png").getPath();
break;
}
URL resource = getClass().getClassLoader().getResource(filePath);
filePath = resource.getFile();
session.setAttribute("questionImagePath", filePath);
session.setAttribute("imageNumber", randomImage);
System.out.println("QuestionfilePath : " + filePath);
return filePath;
}
/**
* @param session : 사용자 session
* @return 잘못된 모자이크 이미지 만들기
*/
public String getWrongRandomMosaicImage(HttpSession session) {
int questionImage = 1;
if(session.getAttribute("imageNumber") != null)
questionImage = (int) session.getAttribute("imageNumber");
int randomImage = (int) (Math.random() * 6) + 1;
while (true) {
if (questionImage != randomImage)
break;
else
randomImage = (int) (Math.random() * 6) + 1;
}
String filePath = "";
switch (randomImage) {
case 1:
filePath = new ClassPathResource("image/captcha/mosaic/mosaic_1.png").getPath();
break;
case 2:
filePath = new ClassPathResource("image/captcha/mosaic/mosaic_2.png").getPath();
break;
case 3:
filePath = new ClassPathResource("image/captcha/mosaic/mosaic_3.png").getPath();
break;
case 4:
filePath = new ClassPathResource("image/captcha/mosaic/mosaic_4.png").getPath();
break;
case 5:
filePath = new ClassPathResource("image/captcha/mosaic/mosaic_5.png").getPath();
break;
case 6:
filePath = new ClassPathResource("image/captcha/mosaic/mosaic_6.png").getPath();
break;
}
URL resource = getClass().getClassLoader().getResource(filePath);
filePath = resource.getFile();
System.out.println("wrongFilePath : " + filePath);
return filePath;
}
/**
* @param file : 리사이즈할 파일
* @param width : 리사이즈할 넓이
* @param height : 리사이즈할 높이
* @return 리사이즈된 이미지
* @throws IOException
*/
public BufferedImage resize(File file, int width, int height) throws IOException {
/** 이미지 가져오기 **/
InputStream inputStream = new FileInputStream(file);
/** 받은 이미지 읽기 **/
BufferedImage inputImage = ImageIO.read(inputStream);
/** 문제 이미지의 자를 부분의 크기와 위치 범위가 정해져있기 때문에 동일한 크기로 리사이징 **/
BufferedImage outputImage = new BufferedImage(width, height, inputImage.getType());
Graphics2D graphics2D = outputImage.createGraphics();
graphics2D.drawImage(inputImage, 0, 0, width, height, null); // 그리기
graphics2D.dispose(); // 자원해제
return outputImage;
}
/**
* @param session : 사용자 session
* @why 모자이크로 만들 자를 이미지 X, Y 좌표를 설정
*/
public void setCutXYPoint(HttpSession session) {
int cutXPoint;
int cutYPoint;
/** session이 안 잡힌 경우 예외처리 **/
if (session.getAttribute("XPoint") == null || session.getAttribute("YPoint") == null) {
cutXPoint = (int) (Math.random() * 400);
cutYPoint = (int) (Math.random() * 400);
session.setAttribute("XPoint", cutXPoint);
session.setAttribute("YPoint", cutYPoint);
/** session 영역이 존재하는 경우 **/
} else {
cutXPoint = (int) (Math.random() * 400);
cutYPoint = (int) (Math.random() * 400);
session.setAttribute("XPoint", cutXPoint);
session.setAttribute("YPoint", cutYPoint);
}
}
/**
* @param blackBoxImage : 블랙박스 이미지
* @param blackBoxWidth : 블랙박스 넓이
* @param blackBoxHeight : 블랙박스 높이
* @param session : 사용자 session
* @why 자른 모자이크를 검은색 사각형 박스로 덮어씌우기
*/
public void drawBlackBox(BufferedImage blackBoxImage, int blackBoxWidth, int blackBoxHeight, HttpSession session) {
int cutXPoint = (int) session.getAttribute("XPoint"); // 왼쪽 상단 X좌표
int cutYPoint = (int) session.getAttribute("YPoint"); // 왼쪽 상단 Y좌표
/** 블랙박스 그리기 **/
Graphics graphics = blackBoxImage.getGraphics();
graphics.setColor(Color.BLACK);
graphics.fillRect(cutXPoint, cutYPoint, blackBoxWidth, blackBoxHeight); // 채우기 사각형
// graphics.drawRect(cutXPoint, cutYPoint, blackBoxWidth, blackBoxHeight); // 테두리 사각형
graphics.dispose();
}
/**
*
* @param numberToDraw : 자른 객곽신 이미지 위에 그릴 숫자
* @return 자른 객관식 이미지 위에 객관식 번호 기입한 이미지
*/
public BufferedImage drawNumberOnMultipleChoiceImage(String numberToDraw) {
/** 이미지화할 글자 설정 **/
int imageWidth = 550; // 문제 이미지 넓이
int imageHeight = 100; // 문제 이미지 높이
Color color = new Color(255, 0, 0); // 글자 색
Font font = new Font("TimeRoman", Font.PLAIN, 35); // 이미지 글체
ImageVo stringImage = new ImageVo(imageWidth, imageHeight, color, font);
/** 문자를 그릴 종이 만들기 **/
BufferedImage image = getWhitePaper(stringImage);
/** 문제 받아오기 **/
String question = numberToDraw;
/** 글자 이미지가 생성될 위치 선정 **/
Graphics2D graphics2 = image.createGraphics(); // Graphics2D 와 BufferedImage는 연동 된 느낌?
/** 글자색과 글자체 받아오기 **/
graphics2.setColor(stringImage.getImageColor());
graphics2.setFont(stringImage.getFont());
/** 해당 내용으로 그리기 작업 **/
graphics2.drawString(question, 0, 40);
graphics2.dispose();
return image;
}
/**
* @param session : 사용자 session
* @return 문제에서 자를 이미지 가져오기
*/
public BufferedImage getMosaicQuestionImage(HttpSession session) throws IOException {
MosaicCaptcha mosaic = new MosaicCaptcha();
/** 랜덤 이미지 받기 **/
String fileImagePath = mosaic.getWrongRandomMosaicImage(session);
/** 리사이즈할 파일 정보 받기 **/
File file = new File(fileImagePath);
int resizedWidth = 500; // 리사이즈할 가로 길이
int resizedHeight = 500; // 리사이즈할 세로 길이
/** 리사이징 **/
BufferedImage resizedImage = mosaic.resize(file, resizedWidth, resizedHeight);
/** 문제 이미지의 자를 부분의 크기와 위치 설정 **/
int cutWidth = 100; // 자를 넓이
int cutHeight = 100; // 자를 높이
int cutXPoint = (int) (Math.random() * 400); // 랜덤 X포인트 (자를 왼쪽 상단 위치)
int cutYPoint = (int) (Math.random() * 400); // 랜덤 Y포인트 (자를 왼쪽 상단 위치)
BufferedImage cutImage = resizedImage.getSubimage(cutXPoint, cutYPoint, cutWidth, cutHeight); // 잘린 이미지
return cutImage;
}
/**
* @param session : 사용자 session
* @return 잘린 정답 이미지
*/
public BufferedImage getMosaicAnswerImage(HttpSession session) throws IOException {
MosaicCaptcha mosaic = new MosaicCaptcha();
/** 문제 이미지 경로 **/
String fileImagePath = (String) session.getAttribute("questionImagePath");
File file = new File(fileImagePath); // 리사이즈할 파일 정보 받기
int resizedWidth = 500; // 리사이즈할 가로 길이
int resizedHeight = 500; // 리사이즈할 세로 길이
/** 리사이징 **/
BufferedImage resizedImage = mosaic.resize(file, resizedWidth, resizedHeight);
/** 문제 이미지의 자를 부분의 크기와 위치 설정 **/
int cutWidth = 100; // 자를 넓이
int cutHeight = 100; // 자를 높이
int cutXPoint = (int) session.getAttribute("XPoint"); // 왼쪽 상단 X좌표
int cutYPoint = (int) session.getAttribute("YPoint"); // 왼쪽 상단 Y좌표
/** 잘린 이미지 **/
BufferedImage cutImage = resizedImage.getSubimage(cutXPoint, cutYPoint, cutWidth, cutHeight);
return cutImage;
}
/**
* @param customImage : 그림을 그릴 종이 설정
* @return 그림을 그릴 종이
*/
public BufferedImage getWhitePaper(ImageVo customImage) {
// 글자를 그릴 종이 크기 설정
int width = customImage.getImageWidth();
int height = customImage.getImageHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
return image;
}
}
Util
package com.lsj.study.vo;
import java.awt.Color;
import java.awt.Font;
public class ImageVo {
private int imageWidth;
private int imageHeight;
private Color imageColor;
private Font font;
public ImageVo(int imageWidth, int imageHeight, Color imageColor, Font font) {
this.imageWidth = imageWidth;
this.imageHeight = imageHeight;
this.imageColor = imageColor;
this.font = font;
}
public int getImageWidth() {
return imageWidth;
}
public void setImageWidth(int imageWidth) {
this.imageWidth = imageWidth;
}
public int getImageHeight() {
return imageHeight;
}
public void setImageHeight(int imageHeight) {
this.imageHeight = imageHeight;
}
public Color getImageColor() {
return imageColor;
}
public void setImageColor(Color imageColor) {
this.imageColor = imageColor;
}
public Font getFont() {
return font;
}
public void setFont(Font font) {
this.font = font;
}
}
Vo
📝숫자 더하기
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<html>
<head>
<title>Number Captcha</title>
<!-- CSS -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
crossorigin="anonymous">
<!-- JS -->
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div class="row justify-content-center">
<div class="col-3"></div>
<div class="col-6">
<div class="row">
<img src="/captcha/number/question" />
</div>
<div class="row text-center">
<div class="col">
<input class="form-control" id="userAnswer" type="text"
placeholder="정답을 입력해주세요">
</div>
<div class="col-3">
<button class="btn btn-primary" onClick="showResult()">제출</button>
</div>
</div>
<div class="row mt-3" id="result" style="color: red;"></div>
</div>
<div class="col-3"></div>
</div>
<script
src="<%=request.getContextPath()%>/resources/js/captcha/captcha_number.js"></script>
</body>
</html>
View
let checkAnswer = async () => {
let userAnswer = document.getElementById('userAnswer').value
let response = await
fetch("/captcha/number/answer?userAnswer=" + userAnswer, {
method: "GET",
});
return response.json();
}
let showResult = () => {
checkAnswer().then((result) => {
if(result.response === "right") alert("정답입니다");
else if(result.response === "wrong") alert("오답입니다");
});
}
$("#userAnswer").keydown(function(key) {
if (key.keyCode == 13) {
showResult();
}
});
JavaScript
package com.lsj.study.controller;
import java.awt.Color;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.lsj.study.Util.NumberCaptcha;
import com.lsj.study.Vo.ImageVo;
@Controller
public class CaptchaController {
/** ------------ Number CaptCha Page ------------ **/
@GetMapping(value = "/captcha/number")
public String captchaNumber(HttpServletRequest request) {
/** Referer 필요시 사용 **/
// String referer = request.getHeader("Referer");
//
// if (referer.equals(rightReferer)) return "captcha/captcha_number";
// else return "captcha/wrong_page";
return "captcha/captcha_number";
}
/** ------------ Number CaptCha Question (문제)------------ **/
@GetMapping(value = "/captcha/number/question")
public void getNumberCaptcha(HttpServletResponse response, HttpSession session)
throws IOException {
NumberCaptcha numberCaptcha = new NumberCaptcha();
OutputStream out = response.getOutputStream(); // 현재 화면에 뿌릴 outputStream
/** 이미지화할 글자 설정 **/
int imageWidth = 1000; // 문제 이미지 넓이
int imageHeight = 500; // 문제 이미지 높이
Color color = new Color(255, 0, 0); // 글자 색
Font font = new Font("TimeRoman", Font.PLAIN, 100); // 이미지 글체
ImageVo stringImage = new ImageVo(imageWidth, imageHeight, color, font);
/** 문자를 그릴 종이 만들기 **/
BufferedImage image = numberCaptcha.getWhitePaper(stringImage);
/** 문제 받아오기 **/
String question = numberCaptcha.getQuestion(session);
/** 종이(image)에 문제(questino)을 그리기 **/
numberCaptcha.draw(image, stringImage, question);
/** 이미지화된 글자의 content-type 설정 **/
response.setContentType("image/png");
/** 만든 이미지를 out(화면)에 png로 생성 **/
ImageIO.write(image, "png", out);
}
/** ------------ Number CaptCha Confrim (정답 확인) ------------ **/
@GetMapping(value = "/captcha/number/answer")
public @ResponseBody Map<Object, Object> confirmNumberCaptcha(HttpServletRequest request, HttpSession session) {
Map<Object, Object> result = new HashMap<>();
/** 정답 가져오기 **/
session = request.getSession();
String answer = (String) session.getAttribute("answer"); // 정답
String userAnswer = request.getParameter("userAnswer"); // 유저 정답
/** 정답 확인 **/
if (userAnswer.equals(answer)) result.put("response", "right");
else result.put("response", "wrong");
return result;
}
}
Controller
package com.lsj.study.Util;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.servlet.http.HttpSession;
import com.lsj.study.Vo.ImageVo;
public class NumberCaptcha {
/**
* @param customImage : 글자 그릴 종이 설정
* @return : 글자 그릴 종이
*/
public BufferedImage getWhitePaper(ImageVo customImage) {
// 글자를 그릴 종이 크기 설정
int width = customImage.getImageWidth();
int height = customImage.getImageHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
return image;
}
/**
* @param session : 사용자 session
* @return : 랜덤 숫자 더하기 문제 생성
*/
public String getQuestion(HttpSession session) {
// 1번째 2번째 랜덤 숫자
int firstNum = (int) (Math.random() * 10 + 1);
int secondNum = (int) (Math.random() * 10 + 1);
// session에 답 저장
int answer = firstNum + secondNum;
session.setAttribute("answer", String.valueOf(answer));
System.out.println("Number-answer : " + answer);
// 문제 만들기
String question = String.valueOf(firstNum) + " + " + String.valueOf(secondNum) + " = ?";
return question;
}
/**
* @param image : 그림 그릴 종이
* @param imageVo : 그림 그릴 종이 설정
* @param question : 그림에 그릴 문제
*/
public void draw(BufferedImage image, ImageVo imageVo, String question) {
// 글자 이미지가 생성될 위치 선정
int left = 240;
int top = 300;
// Graphics2D 와 BufferedImage는 연동 된 느낌?
Graphics2D graphics = image.createGraphics();
// 글자색과 글자체 받아오기
graphics.setColor(imageVo.getImageColor());
graphics.setFont(imageVo.getFont());
// 해당 내용으로 그리기 작업
graphics.drawString(question, left, top);
graphics.dispose();
}
}
Util
package com.lsj.study.Vo;
import java.awt.Color;
import java.awt.Font;
public class ImageVo {
private int imageWidth;
private int imageHeight;
private Color imageColor;
private Font font;
public ImageVo(int imageWidth, int imageHeight, Color imageColor, Font font) {
this.imageWidth = imageWidth;
this.imageHeight = imageHeight;
this.imageColor = imageColor;
this.font = font;
}
public int getImageWidth() {
return imageWidth;
}
public void setImageWidth(int imageWidth) {
this.imageWidth = imageWidth;
}
public int getImageHeight() {
return imageHeight;
}
public void setImageHeight(int imageHeight) {
this.imageHeight = imageHeight;
}
public Color getImageColor() {
return imageColor;
}
public void setImageColor(Color imageColor) {
this.imageColor = imageColor;
}
public Font getFont() {
return font;
}
public void setFont(Font font) {
this.font = font;
}
}
Vo
📝모자이크
📝같은 색 맞추기
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<html>
<head>
<title>Color</title>
<!-- CSS -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
crossorigin="anonymous">
<!-- JS -->
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div class="row justify-content-center">
<div class="col-3"></div>
<div class="col-6">
<div class="row mb-3">
<img src="/captcha/color/question" />
</div>
<div class="row mb-3 text-center">
<b>위와 동일한 색상 번호를 입력해주세요</b>
</div>
<div class="row">
<img src="/captcha/color/multiple/choice" />
</div>
<div class="row mt-4 mb-2">
<input class="form-control" id="userAnswer" type="text"
placeholder="정답을 입력해주세요">
</div>
<div class="row">
<button class="btn btn-primary" onClick="showResult()">제출</button>
</div>
</div>
<div class="col-3"></div>
</div>
<script
src="<%=request.getContextPath()%>/resources/js/captcha/captcha_color.js"></script>
</body>
</html>
View
let checkAnswer = async () => {
let userAnswer = document.getElementById('userAnswer').value;
let response = await
fetch("/captcha/color/answer?userAnswer=" + userAnswer, {
method: "GET",
});
return response.json();
}
let showResult = () => {
checkAnswer().then((result) => {
if(result.response === "right") alert("정답입니다");
else if(result.response === "wrong") alert("오답입니다");
});
}
$("#userAnswer").keydown(function(key) {
if (key.keyCode === 13) {
showResult();
}
});
JavaScript
package com.lsj.study.controller;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.lsj.study.Util.ColorCaptcha;
@Controller
public class CaptchaController {
/** ------------ Color CaptCha Page ------------ **/
@GetMapping(value = "/captcha/color")
public String captchaColor(HttpServletRequest request) {
/** Referer 필요시 사용 **/
//String referer = request.getHeader("Referer");
//if (referer.equals(rightReferer)) return "captcha/captcha_color";
//else return "captcha/wrong_page";
return "captcha/captcha_color";
}
/** ------------ Color CaptCha Question (문제의 공) ------------ **/
@GetMapping(value = "/captcha/color/question")
public void colorQuestion(HttpServletResponse response, HttpSession session) throws IOException {
/** 기존에 남아있는 정답 번호 삭제 **/
session.removeAttribute("colorAnswer");
ColorCaptcha colorCaptcha = new ColorCaptcha();
BufferedImage questionImage = colorCaptcha.drawQuestionColorBall(600, 200, session);
OutputStream out = response.getOutputStream(); // response outputStream
/** 이미지화된 글자의 content-type 설정 **/
response.setContentType("image/png");
/** 만든 이미지를 out(화면)에 png로 생성 **/
ImageIO.write(questionImage, "png", out);
}
/** ------------ Color CaptCha Multiple Choice (선택할 공) ------------ **/
@GetMapping(value = "/captcha/color/multiple/choice")
public void getMultipleChoice(HttpServletResponse response,HttpSession session) throws IOException {
ColorCaptcha colorCaptcha = new ColorCaptcha();
BufferedImage wrongImage1 = colorCaptcha.drawRandomColorBall(100, 100, session);
BufferedImage wrongImage2 = colorCaptcha.drawRandomColorBall(100, 100, session);
BufferedImage wrongImage3 = colorCaptcha.drawRandomColorBall(100, 100, session);
BufferedImage answerImage = colorCaptcha.drawAnswerColorBall(100, 100, session);
OutputStream out = response.getOutputStream(); // 현재 화면에 뿌릴 outputStream
/** 객관식 정보 담기 **/
Map<String, BufferedImage> multipleChoiceMap = new HashMap<String, BufferedImage>();
multipleChoiceMap.put("wrong1", wrongImage1);
multipleChoiceMap.put("wrong2", wrongImage2);
multipleChoiceMap.put("wrong3", wrongImage3);
multipleChoiceMap.put("answer", answerImage);
/** 객관식 번호 섞기 **/
List<String> keys = new ArrayList(multipleChoiceMap.keySet());
Collections.shuffle(keys);
/** 객관식 번호 부여하기 **/
BufferedImage questionNum1 = colorCaptcha.drawNumberOnColorBall("1");
BufferedImage questionNum2 = colorCaptcha.drawNumberOnColorBall("2");
BufferedImage questionNum3 = colorCaptcha.drawNumberOnColorBall("3");
BufferedImage questionNum4 = colorCaptcha.drawNumberOnColorBall("4");
/** key로 정답을 찾아 session 영역에 저장 **/
int answerNum = keys.indexOf("answer");
session.setAttribute("colorAnswer", answerNum + 1);
System.out.println("Color-Answer : " + (answerNum + 1) );
/** 객관식 리스트 합쳐 하나의 이미지로 재구성 **/
try {
/** 기본 바탕화면 구성 **/
BufferedImage mergedImage = new BufferedImage(600, 100, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = (Graphics2D) mergedImage.getGraphics();
graphics.setPaint(new Color(255, 255, 255));
graphics.fillRect(0, 0, mergedImage.getWidth(), mergedImage.getHeight());
/** 객관식 리스트 **/
graphics.drawImage(multipleChoiceMap.get(keys.get(0)), 50, 0, null);
graphics.drawImage(multipleChoiceMap.get(keys.get(1)), 200, 0, null);
graphics.drawImage(multipleChoiceMap.get(keys.get(2)), 350, 0, null);
graphics.drawImage(multipleChoiceMap.get(keys.get(3)), 500, 0, null);
/** 객관식 리스트의 번호 부여 **/
graphics.drawImage(questionNum1, 70, 0, null);
graphics.drawImage(questionNum2, 220, 0, null);
graphics.drawImage(questionNum3, 370, 0, null);
graphics.drawImage(questionNum4, 520, 0, null);
/** 화면에 출력 **/
response.setContentType("image/png");
ImageIO.write(mergedImage, "png", out);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
/** ------------ Color CaptCha Confirm ------------ **/
@GetMapping(value = "/captcha/color/answer")
public @ResponseBody Map<Object, Object> confirmCaptChaColor
(HttpServletRequest request,HttpSession session) {
Map<Object, Object> result = new HashMap<>();
/** 정답 가져오기 **/
session = request.getSession();
String answer = String.valueOf((int) session.getAttribute("colorAnswer")); // 정답
String userAnswer = request.getParameter("userAnswer"); // 유저 정답
/** 정답 확인 **/
if (userAnswer.equals(answer)) result.put("response", "right");
else result.put("response", "wrong");
return result;
}
}
Controller
package com.lsj.study.Util;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.servlet.http.HttpSession;
import com.lsj.study.Vo.ImageVo;
public class ColorCaptcha {
/**
* @param : width - 공 넓이
* height - 공 높이
* session - 사용자 Session
* @return : 문제로 낼 색칠된 공 이미지
*/
public BufferedImage drawQuestionColorBall(int width, int height, HttpSession session) {
session.removeAttribute("colorR");
session.removeAttribute("colorG");
session.removeAttribute("colorB");
BufferedImage questionImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = (Graphics2D) questionImage.getGraphics();
int colorR = (int) (Math.random() * 255);
int colorG = (int) (Math.random() * 255);
int colorB = (int) (Math.random() * 255);
session.setAttribute("colorR", colorR);
session.setAttribute("colorG", colorG);
session.setAttribute("colorB", colorB);
graphics.setColor(new Color(colorR, colorG, colorB));
int xPoint = 250;
int yPoint = 25;
int ovalWidth = 150;
int ovalHeight = 150;
graphics.fillOval(xPoint, yPoint, ovalWidth, ovalHeight); // 채우기 원
// graphics.drawOval(xPoint, yPoint, ovalWidth, ovalHeight); // 테두리 원
graphics.dispose();
return questionImage;
}
/**
*
* @param : width - 공 넓이
* height - 공 높이
* session - 사용자 Session
* @return : 랜덤으로 색칠된 오답인 공 이미지
*/
public BufferedImage drawRandomColorBall(int width, int height, HttpSession session) {
int answerR = 120;
if(session.getAttribute("colorR") != null)
answerR = (int) session.getAttribute("colorR");
BufferedImage questionImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = (Graphics2D) questionImage.getGraphics();
/** 정답과 중복 안되게 만들기 **/
int colorR;
if(answerR > 200) colorR = (int) (Math.random() * 150);
else if (answerR > 150) colorR = (int) (Math.random() * 100);
else if (answerR > 100) colorR = (int) (Math.random() * 100) + 50;
else if (answerR > 50) colorR = (int) (Math.random() * 100) + 100;
else colorR = (int) (Math.random() * 150) + 100;
int colorG = (int) (Math.random() * 255);
int colorB = (int) (Math.random() * 255);
graphics.setPaint(new Color(255, 255, 255));
graphics.setColor(new Color(colorR, colorG, colorB));
int xPoint = 0;
int yPoint = 0;
int ovalWidth = 100;
int ovalHeight = 100;
graphics.fillOval(xPoint, yPoint, ovalWidth, ovalHeight);
graphics.dispose();
return questionImage;
}
/**
* @param : width - 공 넓이
* height - 공 높이
* session - 사용자 Session
* @return : 정답인 색공 설정
*/
public BufferedImage drawAnswerColorBall(int width, int height, HttpSession session) {
int answerR = (int) session.getAttribute("colorR");
int answerG = (int) session.getAttribute("colorG");
int answerB = (int) session.getAttribute("colorB");
System.out.println("answerR : " + answerR);
System.out.println("answerG : " + answerG);
System.out.println("answerB : " + answerB);
BufferedImage questionImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = (Graphics2D) questionImage.getGraphics();
graphics.setPaint(new Color(255, 255, 255));
graphics.setColor(new Color(answerR, answerG, answerB));
int xPoint = 0;
int yPoint = 0;
int ovalWidth = 100;
int ovalHeight = 100;
graphics.fillOval(xPoint, yPoint, ovalWidth, ovalHeight);
graphics.dispose();
return questionImage;
}
/**
* @param : NumberToDraw - 공에 그릴 숫자
* @return : 오답 및 정답 색깔 공에 객관식 선택 번호 그리기
*/
public BufferedImage drawNumberOnColorBall(String NumberToDraw) {
/** 이미지화할 글자 설정 **/
int imageWidth = 550; // 문제 이미지 넓이
int imageHeight = 100; // 문제 이미지 높이
Color color = new Color(0, 0, 0); // 글자 색
Font font = new Font("TimeRoman", Font.PLAIN, 25); // 이미지 글체
ImageVo stringImage = new ImageVo(imageWidth, imageHeight, color, font);
/** 문자를 그릴 종이 만들기 **/
BufferedImage image = getWhitePaper(stringImage);
/** 문제 받아오기 **/
String question = NumberToDraw;
/** 글자 이미지가 생성될 위치 선정 **/
Graphics2D graphics2 = image.createGraphics(); // Graphics2D 와 BufferedImage는 연동 된 느낌?
/** 글자색과 글자체 받아오기 **/
graphics2.setColor(stringImage.getImageColor());
graphics2.setFont(stringImage.getFont());
/** 해당 내용으로 그리기 작업 **/
graphics2.drawString(question, 0, 40);
graphics2.dispose();
return image;
}
/**
* @param customImage : 그림 그릴 종이 크기 설정
* @return : 그림 그릴 종이
*/
public BufferedImage getWhitePaper(ImageVo customImage) {
// 글자를 그릴 종이 크기 설정
int width = customImage.getImageWidth();
int height = customImage.getImageHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
return image;
}
}
Color Ball Class
package com.lsj.study.Vo;
import java.awt.Color;
import java.awt.Font;
public class ImageVo {
private int imageWidth;
private int imageHeight;
private Color imageColor;
private Font font;
public ImageVo(int imageWidth, int imageHeight, Color imageColor, Font font) {
this.imageWidth = imageWidth;
this.imageHeight = imageHeight;
this.imageColor = imageColor;
this.font = font;
}
public int getImageWidth() {
return imageWidth;
}
public void setImageWidth(int imageWidth) {
this.imageWidth = imageWidth;
}
public int getImageHeight() {
return imageHeight;
}
public void setImageHeight(int imageHeight) {
this.imageHeight = imageHeight;
}
public Color getImageColor() {
return imageColor;
}
public void setImageColor(Color imageColor) {
this.imageColor = imageColor;
}
public Font getFont() {
return font;
}
public void setFont(Font font) {
this.font = font;
}
}
Vo
📝가위바위보
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<html>
<head>
<title>Rock Paper Scissor Captcha</title>
<!-- CSS -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
crossorigin="anonymous">
<!-- JS -->
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div class="row justify-content-center">
<div class="col-2"></div>
<div class="col-8">
<!-- 문제 -->
<div class="row justify-content-center text-center">
<div class="col-2"></div>
<div class="col-8">
<img src='rock-paper-scissor/question' width="200px" height="250px" />
<div class="my-3">
<b>가위 바위 보에서 이기기 위해 내야하는 걸 고르세요</b>
</div>
</div>
<div class="col-2"></div>
</div>
<!-- 객관식 리스트 -->
<div class="row justify-content-center">
<div class="col-2 d-flex align-items-center me-3">
<b class="text-danger">1</b> <img
src="/resources/image/captcha/rock_paper_scissor/rock.JPG"
width="100px" height="100px" />
</div>
<div class="col-2 d-flex align-items-center me-3">
<b class="text-danger">2</b> <img
src="/resources/image/captcha/rock_paper_scissor/paper.JPG"
width="100px" height="100px" />
</div>
<div class="col-2 d-flex align-items-center">
<b class="text-danger">3</b> <img
src="/resources/image/captcha/rock_paper_scissor/scissor.JPG"
width="100px" height="100px" />
</div>
</div>
<!-- 정답란 -->
<div class="row mt-3">
<div class="col-2"></div>
<div class="col-8">
<div class="row">
<input class="form-control my-1" type="text" id="userAnswer"
placeholder="정답번호를 입력해주세요">
</div>
</div>
<div class="col-2"></div>
</div>
<!-- 제출 -->
<div class="row mt-3">
<div class="col-2"></div>
<div class="col-8">
<div class="row">
<button class="btn btn-primary" onClick="showResult()">제출</button>
</div>
</div>
<div class="col-2"></div>
</div>
</div>
<div class="col-2"></div>
</div>
<script
src="<%=request.getContextPath()%>/resources/js/captcha/captcha_rock_paper_scissor.js"></script>
</body>
</html>
View
let checkAnswer = async () => {
let userAnswer = document.getElementById('userAnswer').value
let response = await
fetch("/captcha/roc-paper-scissor/answer?userAnswer=" + userAnswer, {
method: "GET",
});
return response.json();
}
let showResult = () => {
checkAnswer().then((result) => {
if(result.response === "right") alert("정답입니다");
else if(result.response === "wrong") alert("오답입니다");
});
}
$("#userAnswer").keydown(function(key) {
if (key.keyCode == 13) {
showResult();
}
});
JavaScript
package com.lsj.study.controller;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.lsj.study.Util.RockPaperScissorCaptcha;
@Controller
public class CaptchaController {
/** ------------ Rock Paper Scissor CaptCha Page ------------ **/
@GetMapping(value = "/captcha/rock-paper-scissor")
public String rockPaperScissor(HttpServletRequest request) {
/** Referer 필요시 사용 **/
// String referer = request.getHeader("Referer");
//
// if (referer.equals(rightReferer)) return "captcha/captcha_rock_paper_scissor";
// else return "captcha/wrong_page";
return "captcha/captcha_rock_paper_scissor";
}
/** ------------ Rock Paper Scissor CaptCha Question ------------ **/
@GetMapping(value = "/captcha/rock-paper-scissor/question")
public void getRockPaperScissorQuestion(HttpServletResponse response, HttpSession session) throws IOException {
OutputStream out = response.getOutputStream();
RockPaperScissorCaptcha rockPaperScissorCaptcha = new RockPaperScissorCaptcha();
String fileImagePath = rockPaperScissorCaptcha.getRandomImage(session);
File file = new File(fileImagePath); // 리사이즈할 파일 정보
int resizedWidth = 500; // 리사이즈할 가로 길이
int resizedHeight = 500; // 리사이즈할 세로 길이
/** 리사이징 **/
BufferedImage rockPaperScissorImage = rockPaperScissorCaptcha.resize(file, resizedWidth, resizedHeight);
/** 이미지화된 글자의 content-type 설정 **/
response.setContentType("image/png");
/** 만든 이미지를 out(화면)에 png로 생성 **/
ImageIO.write(rockPaperScissorImage, "png", out);
}
/** ------------ Rock Paper Scissor CaptCha Confirm ------------ **/
@GetMapping(value = "/captcha/roc-paper-scissor/answer")
public @ResponseBody Map<Object, Object> confirmCaptChaRockPaperScissor(HttpServletRequest request,HttpSession session) {
Map<Object, Object> result = new HashMap<>();
/** 정답 가져오기 **/
session = request.getSession();
String answer = String.valueOf((int) session.getAttribute("rockPaperScissorAnswer")); // 정답
String userAnswer = request.getParameter("userAnswer"); // 유저 정답
/** 정답 확인 **/
if (userAnswer.equals(answer)) result.put("response", "right");
else result.put("response", "wrong");
return result;
}
}
Controller
package com.lsj.study.Util;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpSession;
import org.springframework.core.io.ClassPathResource;
public class RockPaperScissorCaptcha {
/**
* @param session : 사용자 session
* @return 가위바위보 랜덤 이미지 경로 가져오기
*/
public String getRandomRockPaperScissorPath(HttpSession session) throws IOException {
/** 기존 정답 없애기 **/
session.removeAttribute("rockPaperScissorAnswer");
/** 정답과 문제 받아오기 **/
int randomImage = (int) (Math.random() * 3) + 1;
String filePath = "";
int answerNum = 0;
switch (randomImage) {
case 1:
filePath = new ClassPathResource("image/captcha/rock_paper_scissor/rock.JPG").getPath();
answerNum = 2;
break;
case 2:
filePath = new ClassPathResource("image/captcha/rock_paper_scissor/paper.JPG").getPath();
answerNum = 3;
break;
case 3:
filePath = new ClassPathResource("image/captcha/rock_paper_scissor/scissor.JPG").getPath();
answerNum = 1;
break;
}
URL resource = getClass().getClassLoader().getResource(filePath);
filePath = resource.getFile();
session.setAttribute("rockPaperScissorAnswer", answerNum);
return filePath;
}
/**
* @param file : 리사이즈할 이미지
* @param width : 리사이즈할 넓이
* @param height : 리사이즈할 높이
* @return 리사이즈 된 이미지
*/
public BufferedImage resize(File file, int width, int height) throws IOException {
/** 이미지 가져오기 **/
InputStream inputStream = new FileInputStream(file);
/** 받은 이미지 읽기 **/
BufferedImage inputImage = ImageIO.read(inputStream);
/** 내가 원하는 크기로 리사이징 **/
BufferedImage outputImage = new BufferedImage(width, height, inputImage.getType());
Graphics2D graphics2D = outputImage.createGraphics();
graphics2D.drawImage(inputImage, 0, 0, width, height, null); // 그리기
graphics2D.dispose(); // 자원해제
return outputImage;
}
}
Util
📝랜덤으로 Captcha Image 가져오기
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<html>
<head>
<title>Captcha</title>
<!-- CSS -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
crossorigin="anonymous">
<!-- JS -->
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div id="captcha"></div>
<script
src="<%=request.getContextPath()%>/resources/js/captcha/captcha.js"></script>
</body>
</html>
View
$(document).ready(function() {
captchaLinks = ["captcha/number", "captcha/mosaic", "captcha/color", "captcha/rock-paper-scissor"];
shuffle(captchaLinks);
var tag = "<iframe src='http://localhost:8080/" + captchaLinks[0] + "' scrolling='no' width='100%' height='100%'/>"
var captcha = document.getElementById("captcha");
captcha.innerHTML = tag;
});
function shuffle(array) {
array.sort(() => Math.random() - 0.5);
}
JavaScript
package com.lsj.study.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class CaptchaController {
/** ------------ CaptCha ------------ **/
@GetMapping(value = "/captcha")
public String captCha() {
return "captcha/captcha";
}
}
Java
src/main/resource → 비즈니스 로직에서의 이미지 경로
webapp/resources → JSP에서의 이미지 경로
반응형
'[Java] > [Java Code]' 카테고리의 다른 글
[Java Code] [클린코드] Boolean OR절 축약 (0) | 2023.12.08 |
---|---|
[Java Code] 자바 주민등록번호 랜덤 생성 (윤년 고려 X) (0) | 2023.05.30 |
[Java Code] 영문오타 한글로 교정시키는 코드 (띄어쓰기는 적용 안 됨) [영문오타교정] (0) | 2023.05.29 |
[Java Code] yyyymmdd 날짜 계산하기, HHmmss 시간 계산하기 (두 날짜 또는 시간 빠른 순서 찾기) (0) | 2022.12.01 |
[Java Code] ini 설정 파일 읽기 (0) | 2022.11.05 |