Struts 2 + Spring + iBatis 기반 웹 응용 최 적 실천 시리즈 6 (인증 코드 편)
우선 우리 가 만 든 checkcode 를 저장 하기 위해 CheckCode Session 클래스 가 있어 야 합 니 다.이 종 류 는 매우 간단 합 니 다. 주로 인증 코드 자체, 생 성 시간 과 효과 적 인 표 지 를 저장 하 는 것 입 니 다.
public class CheckCodeSession {
private String checkCode;//
private long createTime;//
private boolean validate = false;// ( )
public String getCheckCode() {
return checkCode;
}
public void setCheckCode(String checkCode) {
this.checkCode = checkCode;
}
public long getCreateTime() {
return createTime;
}
public void setCreateTime(long createTime) {
this.createTime = createTime;
}
public boolean isValidate() {
return validate;
}
public void setValidate(boolean validate) {
this.validate = validate;
}
}
checkcode aciton 을 다시 보 겠 습 니 다.이 는 0 - 90 개의 숫자 중에서 랜 덤 으로 4 개 를 checkcode, 즉 인증 코드 자체 로 선택 하고 생 성 된 인증 코드 를 checkCodeSession 에 할당 하 며 유효 하 게 설정 합 니 다.Check CodeSession Aware 라 는 인터페이스 도 실현 했다.
public class CheckCodeAction implements Action, CheckCodeSessionAware {
private static final long serialVersionUID = 1L;
private String checkCode;
private CheckCodeSession checkCodeSession;
private int codeLenght = 4;
private static char[] codes={'0','1','2','3','4','5','6','7','8','9'};
public String execute() throws Exception {
Random random = new Random();
char[] checkCodeChararray = new char[codeLenght];
for(int i=0;i<codeLenght;i++){
checkCodeChararray[i] = codes[random.nextInt(codes.length)];
}
checkCode = String.valueOf(checkCodeChararray);
checkCodeSession.setCheckCode(checkCode);
checkCodeSession.setCreateTime(System.currentTimeMillis());
checkCodeSession.setValidate(true);
return SUCCESS;
}
public String getCheckCode() {
return checkCode;
}
public void setCheckCodeSession(CheckCodeSession checkCodeSession) {
this.checkCodeSession = checkCodeSession;
}
public void setCodeLenght(int codeLenght) {
this.codeLenght = codeLenght;
}
public CheckCodeSession getCheckCodeSession() {
return checkCodeSession;
}
}
Check CodeSession Aware 인터페이스, 이 인 터 페 이 스 는 매우 간단 합 니 다. getter, setter 방법 은 두 개 밖 에 없습니다.
public interface CheckCodeSessionAware {
public void setCheckCodeSession(CheckCodeSession checkCodeSession);
public CheckCodeSession getCheckCodeSession();
}
현재 우 리 는 checkcode 와 checkcode 를 생 성 하 는 aciton 이 있 습 니 다. 그러면 구체 적 으로 검증 기능 을 어떻게 실현 합 니까?이것 은 Struts 2 의 검증 프레임 워 크 와 관련 되 어야 합 니 다. 우 리 는 코드 를 보고 CheckCodeSession Aware 인터페이스 와 결합 하여 CheckCodeValidator 가 checkcode 에 대한 검증 기능 을 실현 해 야 합 니 다.
public class CheckCodeValidator extends FieldValidatorSupport {
private static Logger logger = Logger.getLogger(CheckCodeValidator.class);
public void validate(Object object) throws ValidationException {
Object obj = getFieldValue(getFieldName(), object);
CheckCodeSession checkCodeSession = null;
if(object instanceof CheckCodeSessionAware){
checkCodeSession = ((CheckCodeSessionAware)object).getCheckCodeSession();
if(checkCodeSession == null){
logger.error("action: "+ object +" not implements CheckCodeSessionAware.class");
}
}
String checkCode = (String) obj;
if(StringUtil.isEmpty(checkCode) || checkCodeSession == null || !checkCodeSession.isValidate()){
this.addFieldError(getFieldName(), object);
}else{
if(checkCode.equalsIgnoreCase(checkCodeSession.getCheckCode())){
checkCodeSession.setValidate(false);
}else{
this.addFieldError(getFieldName(), object);
}
}
}
Struts 2 프레임 워 크 는 매우 유연 하 게 설계 되 어 검증 자체 가 하나의 프레임 워 크 가 될 수 있 습 니 다. 우리 의 Check CodeValidator 는 FieldValidator Support 를 간단하게 계승 하면 하나의 vaidator 가 될 수 있 고 응용 프로그램 에서 간단 한 설정 만 하면 사용 할 수 있 습 니 다.
페이지 에 인증 코드 를 표시 하 는 방법 을 살 펴 보 겠 습 니 다. 여기 서 프레임 워 크 에 대한 확장 도 있 습 니 다. 저희 Check Code ResultType 은 StrutsResultSupport 를 계승 하여 새로운 result type 이 되 었 습 니 다.여기 서 자바 2d api 를 사용 하여 checkcode 의 값 에 따라 그림 을 만 든 후 http Response 에 직접 기록 합 니 다.주의해 야 할 것 은 http header 에 No - cache 방식 을 설정 한 것 입 니 다. 이것 은 브 라 우 저 캐 시 checkcode 그림 을 저장 하지 않도록 하기 위 한 것 입 니 다.
public class CheckCodeResultType extends StrutsResultSupport{
protected String contentType = "image/jpeg";
protected int contentLength;
private String checkCode;
/**
* @return Returns the contentType.
*/
public String getContentType() {
return (contentType);
}
/**
* @param contentType The contentType to set.
*/
public void setContentType(String contentType) {
this.contentType = contentType;
}
/**
* @return Returns the contentLength.
*/
public int getContentLength() {
return contentLength;
}
/**
* @param contentLength The contentLength to set.
*/
public void setContentLength(int contentLength) {
this.contentLength = contentLength;
}
/**
* @see com.opensymphony.xwork.Result#execute(com.opensymphony.xwork.ActionInvocation)
*/
protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
try {
// Find the Response in context
HttpServletResponse oResponse = (HttpServletResponse) invocation.getInvocationContext().get(HTTP_RESPONSE);
oResponse.setHeader("Pragma","No-cache");
oResponse.setHeader("Cache-Control","no-cache");
oResponse.setDateHeader("Expires", 0);
// Set the content type
oResponse.setContentType(conditionalParse(contentType, invocation));
// Set the content length
if (contentLength != 0) {
oResponse.setContentLength(contentLength);
}
// Get the outputstream
OutputStream oOutput = oResponse.getOutputStream();
// (4 )
String rand=conditionalParse(checkCode, invocation);
//
int width=60, height=24;
if(rand!= null){
width = 17 * rand.length();
}
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//
Graphics g = image.getGraphics();
//
Random random = new Random();
//
g.setColor(getRandColor(200,250));
g.fillRect(0, 0, width, height);
//
Font font = new Font("Times New Roman",Font.BOLD,20);
g.setFont(font);
//
g.setColor(getRandColor(20,50));
g.drawRect(0,0,width-1,height-1);
// 155 ,
g.setColor(getRandColor(160,200));
for (int i=0;i<155;i++)
{
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x,y,x+xl,y+yl);
}
if(rand != null){
for (int i=0;i<rand.length();i++){
//
g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));// , ,
g.drawString(String.valueOf(rand.charAt(i)),15 * i + 7,17);
}
}
//
g.dispose();
//
ImageIO.write(image, "JPEG", oResponse.getOutputStream());
// Flush
oOutput.flush();
}
finally {
}
}
private Color getRandColor(int fc,int bc){//
Random random = new Random();
if(fc>255) fc=255;
if(bc>255) bc=255;
int r=fc+random.nextInt(bc-fc);
int g=fc+random.nextInt(bc-fc);
int b=fc+random.nextInt(bc-fc);
return new Color(r,g,b);
}
public String getCheckCode() {
return checkCode;
}
public void setCheckCode(String checkCode) {
this.checkCode = checkCode;
}
}
지금 우리 가 필요 로 하 는 코드 가 모두 있 습 니 다. 그렇다면 구체 적 인 응용 에서 어떻게 사용 해 야 합 니까?
우선 struts. xml 에 checkcode aciton 을 설정 합 니 다.여기 result type 은 우리 가 정의 한 checkCode 형식 을 사용 합 니 다.
<result-types>
<result-type name="checkCode"
class="com.meidusa.toolkit.web.common.resulttype.CheckCodeResultType" />
</result-types>
<action name="checkCode"
class="com.meidusa.toolkit.web.common.action.CheckCodeAction">
<result name="success" type="checkCode">
<param name="contentType">image/jpeg</param>
<param name="checkCode">${checkCode}</param>
</result>
</action>
그 다음 에 인증 코드 를 사용 해 야 하 는 aciton 에서 도 Check CodeSession Aware 인 터 페 이 스 를 실현 합 니 다. 예 를 들 어 우리 의 login aciton 입 니 다.
public class LoginAction extends ActionSupport implements ClientCookieAware<Cookie>, ClientCookieNotCare, CheckCodeSessionAware{
private Cookie cookie;
private String loginId;
private CheckCodeSession checkCodeSession;
private String checkcode;
public String getCheckcode() {
return checkcode;
}
public void setCheckcode(String checkcode) {
this.checkcode = checkcode;
}
public String getLoginId() {
return loginId;
}
public void setLoginId(String loginId) {
this.loginId = loginId;
}
public Cookie getCookie() {
return cookie;
}
public void setClientCookie(Cookie cookie) {
this.cookie = cookie;
}
public String execute() throws Exception {
cookie.setLoginId(loginId);
cookie.save();
return SUCCESS;
}
public CheckCodeSession getCheckCodeSession() {
return checkCodeSession;
}
public void setCheckCodeSession(CheckCodeSession checkCodeSession) {
this.checkCodeSession = checkCodeSession;
}
}
여기, 아직 매우 중요 한 단계 가 있다.여러분 은 본문 첫머리 에 소 개 된 Check CodeSession 류 와 Check CodeSession Aware 인 터 페 이 스 를 기억 하 십 니까?CheckCodeSession Aware 인터페이스의 기능 은 struts 2 의 vaidation 프레임 워 크 가 vaidate 방법 을 호출 하여 검증 할 때 aciton 에서 CheckCodeSession 대상 을 얻 을 수 있 도록 하 는 것 외 에 도 중요 한 기능 은 spring 으로 하여 금 이 CheckCodeSession 대상 을 주입 하 게 하 는 것 이다.즉, Check CodeSession 은 하나의 bean 으로 spring 에서 설정 해 야 한 다 는 것 이다.여기 서 매우 중요 한 단 계 는 scope 를 session 으로 설정 하여 checkcode aciton 의 CheckCodeSession 과 checkcode 검증 이 필요 한 action (예 를 들 어 여기 login aciton) 의 CheckCodeSession 을 일치 시 키 는 것 입 니 다.세 션 으로 설정 되 어 있 지 않 으 면 인증 프레임 워 크 가 검증 할 때 읽 는 checkcode 값 은 사용자 가 입력 한 값 과 다 릅 니 다.
<bean id="checkCodeSession" class="com.meidusa.toolkit.web.common.components.CheckCodeSession" scope="session" />
이것 은 spring 2.0 의 프로필 을 사용 해 야 합 니 다. 오래된 버 전의 spring 프로필 은 scope 라 는 속성 을 지원 하지 않 습 니 다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
마지막 으로, struts 2 프레임 워 크 에 우리 가 정의 한 추가 validator 를 알려 주 고, 이 파일 을 struts. xml 와 같은 디 렉 터 리 에 놓 아야 합 니 다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator Config 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd">
<validators>
<validator name="checkcode" class="com.meidusa.toolkit.web.common.validators.CheckCodeValidator"/>
</validators>
모든 것 이 설정 되 어 있 는 상황 에서 페이지 에서 checkcode 를 어떻게 사용 하 는 지 다시 한번 봅 시다.
<label> </label><input type="text" name="checkcode" /><img src="/demo/checkCode.action"/></br><s:fielderror/>
마지막 으로, 우리 의 checkcode validator 를 우리 의 loginAction 에 설정 합 니 다.
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<field name="checkcode">
<field-validator type="requiredstring">
<message> </message>
</field-validator>
<field-validator type="checkcode">
<message> !</message>
</field-validator>
</field>
</validators>
이로써 인증 코드 의 실현 에 대해 모두 소 개 했 습 니 다. 이것 은 본 시리즈 의 여섯 번 째 편 입 니 다. 필 자 는 다음 편 에서 데 모 를 보 내 서 여러분 에 게 다운로드 체험 을 제공 하고 전체 시 리 즈 를 끝 낼 것 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
thymeleaf로 HTML 페이지를 동적으로 만듭니다 (spring + gradle)지난번에는 에서 화면에 HTML을 표시했습니다. 이번에는 화면을 동적으로 움직여보고 싶기 때문에 입력한 문자를 화면에 표시시키고 싶습니다. 초보자의 비망록이므로 이상한 점 등 있으면 지적 받을 수 있으면 기쁩니다! ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.