반응형

우선 LoginTest 클래스와 loginTest.html 을 만들어 주겠습니다

LoginTest는 sec04.ex01패키지 내에 만들어 주겠습니다.

login.html은 WebContent에 폴더 test01 생성후 만들어 주었습니다.

프로젝트 실행해 주시고

주소창에 아래와 같이 입력해주세요 localhost:8080/pro06/test01/login.html

아이디와 비밀번호 입력시 뜨는 화면

 

아이디가 없을 시 뜨는 화면

 

반응형
블로그 이미지

꽃꽂이하는개발자

,
반응형

앞에서는 <form>태그에서 바로 서블릿으로 데이터를 전송했지만 전송 전에 로그인하면 id와 비밀번호 입력 유무 체크하기처럼 전송 데이터에 대해 유효성 검사를 하는 경우가 많습니다. 이런 기능은 자바스크립트로 구현하므로 자바스크립트로 서블릿에 요청하는 방법을 알아보겠습니다.

 

우선 LoginServlet5클래스와 login2.html을 만들어보겠습니다.

실습 위치

login2.html을 작성하겠습니다.

<hidden>태그를 이용해 화면에는 보이지 않게 하면서 값을 서블릿으로 전송합니다.

 

비밀번호를 넣지 않았을 때 발생하는 alert창

 

로그인 이후 창

반응형
블로그 이미지

꽃꽂이하는개발자

,
반응형

웹 프로그램에서는 GET방식과 POST방식을 혼합해서 많이 사용합니다.

이럴때마다 일일이 구분한다면 많이 불편하게 됩니다.

그래서 doGet()이나 doPost()메서드로 처리한 후 다시 doHandle()을 호출해서 기능을 구현해 보겠습니다.

 

웹컨텐츠에 login.html 파일 생성

login.html

 

그 후 sec03.ex 패키지에서

NEW - > SERVLET -> 클래스명은 LoginServlet4 -> NEXT -> NEXT 를 하시면

이렇게 체크하여 주고 Finish 하시면 됩니다

하지만 초보자 입장에서는 이렇게 만드는 것 보다는

직접 따라 쳐주시길 권장합니다

NEW- > CLASS (LoginServlet4)

실행후 웹브라우저 창에서 아래와 같이 login.html 까지 쳐주셔야 합니다.

POST방식
get방식

login.html에서 method를 get으로 바꿔보고 해보세요 또는 post로 바꿔보고 해보세요.

 

반응형
블로그 이미지

꽃꽂이하는개발자

,
반응형

post방식은 정보의 보안성이 필요할때 주로 사용

 

다이나믹 웹 프로젝트 생성후

웹 컨텐츠 아래에

login.html에 위의 내용을 적어줍니다.

여기서 method를 method = "get"을 해주면 겟방식 method="post" 로 하면 post방식으로 됩니다.

action="login3"으로 해주면 LoginServlet3클래스 내에 /login3을 찾아가서 처리하게 됩니다.

 

loginServlet3 클래스를 만들고

httpservlet을 상속받으면서 위의 사항을 적어줍니다.

 

GET방식으로 한다면 위의 주소에 아이디와 비밀번호가 보이지만

이렇게 POST방식으로 진행하게 된다면

ID와 PASSWORD가 보이지 않게 됩니다.

반응형
블로그 이미지

꽃꽂이하는개발자

,
반응형

이클립스에서 

Dynamic web project 를 하나 생성하시고

sec02.ex01 패키지에 CalcServlet 클래스를 생성합니다.

CalcServlet.java 클래스에 아래대로 입력을 합니다.

 

 

실행하고

http://localhost:8080/pro06/calc로 요청한 후 원화에 값을 입력하고 변환을 클릭해 봅니다

 

그럼 변환된 값이 출력이 됩니다^^

 

ps. 탐캣이 설치되어 있어야 합니다...

 

package sec02.ex01;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/calc")
public class CalcServlet extends HttpServlet{
private static float USD_RATE = 1124.70F;
private static float JPY_RATE = 10.113F;
private static float CNY_RATE = 163.30F;
private static float GBP_RATE = 1444.35F;
private static float EUR_RATE = 1295.97F;
public void init() {
System.out.println("init 실행");
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
request.setCharacterEncoding("utf-8");
response.setContentType("text/html; charset=utf-8");
PrintWriter pw = response.getWriter();

String command = request.getParameter("command");  //수행할 요청을 받아옵니다.
String won = request.getParameter("won"); //변환할 원화를 받아옵니다.
String operator = request.getParameter("operator"); // 변환할 외화종류를 받아옵니다.

if(command != null && command.equals("calculate")) { //최초 요청 시 command가 null이면 계산기 화면을 출력하고, command값이 calculate이면 계산 결과를 출력합니다.

String result = calculate(Float.parseFloat(won), operator);
pw.print("변환결과"); pw.print(""+ result + ""); pw.print("환율 계산기"); return; } pw.print(""); pw.print("환율 계산기"); pw.print("

");  //환율 정보 입력 후 다시 서블릿 calc로 요청합니다.
pw.print("원화: ");
pw.print("
pw.print(
pw.print(
pw.print(
pw.print(
pw.print(
pw.print(");

pw.print("");
pw.println("");
pw.println("

"); pw.print(""); pw.close(); } // 원화를 선택한 외화로 환산합니다. private static String calculate(float won, String operator) { String result = null; if(operator.equals("dollar")) { result = String.format("%.6f", won / USD_RATE); }else if (operator.equals("en")) { result = String.format("%.6f",  won / JPY_RATE); }else if (operator.equals("wian")) { result = String.format("%.6f", won / CNY_RATE); }else if (operator.equals("pound")) { result = String.format("%.6f", won / GBP_RATE); }else if (operator.equals("euro")) { result = String.format("%.6f", won / EUR_RATE); } return result; }  } ​

반응형
블로그 이미지

꽃꽂이하는개발자

,

Jupyter Notebook

2020/Python 2019. 11. 22. 16:36
반응형

Jupyter Notebook은 web을 통하여 파이썬 코드를 작성하고 실행해 볼 수 있는 개발도구이다.

만약 자신이 아나콘다(Anaconda)를 설치해서 사용하고 있다면 함께 설치되어 Jupyter를 사용할 수 있다.

하지만 아나콘다를 사용하지 않는 경우 pip를  통해 Jupyter 패키지를 설치할 수 있다.

 

아나콘다를 사용할 경우 자신이 사용할 폴더에 새로운 텍스트 파일을 만들어 준다.

이곳에 가상환경 세팅을 해 줍니다

activate bitenv && jupyter notebook .

이렇게 입력해주고 저장한 후 파일명과 확장자명을 바꿔주었습니다.

더블클릭 하게 되면

 

이러한 창이 뜨게 됩니다.

이때 cmd창을 끄면 안됩니다. 끄면 쥬피터도 꺼집니다.

 

그 후에 Beautiful Soup를 설치해 보겠습니다

Beautiful Soup 라이브러리는 Python에서 기본적으로 제공하는 라이브러리가 아니기 때문에 별도의 설치가 필요합니다

cmd창을 열고 (윈도우+r을 눌러 cmd를 입력) pip install bs4를 입력하시면 설치가 됩니다

(pip는 Python 설치 디렉토리의 Scirpts 폴더 밑에 있어서 해당 위치로 이동하여 명령어를 실행해주세요)

 

 

반응형
블로그 이미지

꽃꽂이하는개발자

,

Python 정규 표현식

2020/Python 2019. 11. 21. 18:57
반응형

#정규 표현식
# 단순 문자열 매칭이 아니라 문자열의 패턴으로 검색하는 것
import re

# 사용시 : 패턴 컴파일 -> 패턴 객체의 메서드로 검색 수행
p = re.compile(r"P[a-z]+")
#[] 패턴 1글자 + 1글자 이상
#대문자 P로 시작하고 소문자(a-z) 1글자 이상 있는 문자열
print(p.match("Life"))# 현재 패턴이 life와 일치하는지?
print("p match Python?", p.match("Python"))
print("p match Pizza?", p.match("Pizza"))

source = "Life is too short, you need Python"
# 방법 1. 패턴 컴파일 후 검색 수행
p = re.compile(r"L[a-z]+")
print(p.match("Life"))

# 방법 2. 축약형, 패턴 문자열과 검색 대상 문자열을 함께 제공
print(re.match(r"[A-Z][a-z]+", source))
# 매치된 내용을 추출할 경우 group() 메서드로 뽑을 수 있다
print("Match 된 내용:", re.match(r"[A-Z][a-z]+", source).group())

#축약 문자
# \d(숫자), \w(문자), \s (공백문자)
# \D(숫자가 아닌 것), \W(문자가 아닌 것), \S(공백문자 아닌것)
# search -> 전체 문자열 대상 패턴 검색
#findall -> 전체 문자열 대상 검색 후 list로 반환
# finditer -> 검색 후 iterator(반복자)를 반환
source = "Paint C JavaScript 123 456 Perl Java Python P123 Ruby"
#p로 시작되는 문자열 패턴만 검색해서 iterator을 반환
iter = re.finditer(r"\bp\w+", source, re.IGNORECASE)
#re.IGNORECASE는 대소문자를 구분하지 말고 검색하라는 의미다

for x in iter:
print("검색된 단어:", x)

# 자주 사용될 수 있는 패턴들
# 전화번호의 예
tel = re.compile(r"(\d{2,3})-(\d{3,4})-(\d{4})")
m = tel.match("010-1234-5678")
print("result:", m)
# () 로 묶은 것은 groups() 메서드로 추출
print("groups:", m.groups()) #groups
#매칭된 전체 내용을 추출: group()
print("매칭된 내용:", m.group()) #group

tel= re.compile(r"(?P<area>\d{2,3})-(?P<exchange>\d{3,4})-(?P<number>\d{4})")
# 그룹핑시 (?P<이름>) 형식을 부여하면 매칭 결과에 이름을 부여할 수 있다
# 이름이 부여된 매칭 결과는 groupdict()메서드로 사전으로 반환받을 수 있다.
m = tel.match("010-1234-5678")
print(m.groups()) # 그룹핑된 결과 확인
print(m.group()) #매칭된 전체 결과
print(m.groupdict()) #부여한 이름을 기반으로 한 dict 객체 반환

# 이메일
pattern = r"\w+[\w\.]*@[\w\.]*\.[a-z]+"
source = "skyun.nam@gmail.com"

print(re.match(pattern, source))

# 한글 매칭 (Unicode 기반)
# 한국어 정규식의 예제
source = "English 대한민국 Japan China"
p = re.compile(r"[-]+")
print(p.findall(source))

반응형
블로그 이미지

꽃꽂이하는개발자

,

Python class

2020/Python 2019. 11. 21. 18:52
반응형

# class
"""
-새로운 이름 공간을 지원하는 단위: 데이터의 설계도
- 새로운 클래스는 새로운 자료형을 정의하는 것
- 인스턴스는 이 자료형의 객체를 생성하는 것
- 클래스와 인스턴스는 직접적인 영향을 갖는다

-인스턴스에서 클래스 멤ㅂ와 접근은 자능
-클래스 맴버에서 인스턴스 멤버의 접근은 불가
"""

class MyString(str): # str은 상속받은 새로운 클래스
pass

#특정 클래스를 상속받지 않을 경우, object 상속
s = MyString() # 생성자 호출
print(type(s))

# 어떤 클래스를 상속 받은 클래스잉ㄴ가?
# __bases__ -> 부모의 목록을 튜플로 반환
print("MyString의 부모:", MyString.__bases__)

#특정 부모를 상속받지 않을 경우() 없어도 된다
class myobj: #object를 상속
pass
print(myobj.__bases__)
#파이썬은 여러 부모로부터의 상속을 허용한다

#파이썬은 여러 부모로부터의 상속을 허용한다
class Complex(str, myobj):
# str로부터 모든 맴버들
#myobj로부터 모든 멤버들을 물려받는다
pass

print("Complex의 부모:", Complex.__bases__)

#특정 클래스가 다른 클래스의 자식인지 확인
# issubclass 함수
print("Complex str의 자식인가?", issubclass(Complex,str))

#클래스의 생성
# 인스턴스를 위한 멤버는 항상 self를 붙여준다
class Point:
# 클래스 멤버:
# 클래스 이름 공간 내에 생성
# 모든 인스턴스 맴버 공유
# 클래스 맴버는 인스턴스 생성 없이도 사용할 수 있다.
instance_count = 0

def __init__(self, x = 0, y = 0): # 생성자
#파이썬은 여러 개의 생성자를 만들 수 없으므로
# 범용적으로 사용될 수 있는 유일한 생성자를 작성
self.x = x
self.y = y
Point.instance_count +=1

#소멸자
def __del__(self):
#객체가 제거될 때 호출
Point.instance_count -= 1

#__str__
def __str__(self):#문자열 출력
#str() 호출 혹은 print를 할 때 사용되는 비공식 문자열(일반 사용자 대상)
return "Point x={}, y={}".format(self.x, self.y)
#__repr__
def __repr__(self): #문자열 출력
# 개발자용, 공식문자열
# repr() 함수로 전달 받을 수 있다.
# 이 문자열로 해당 객체를 복원해 낼 수 있어야 한다.
return "Point({},{})".format(self.x,self.y)

def setX(self,x):
self.x = x
def setY(self, y):
self.y = y
def getX(self):
return self.x
def getY(self):
return self.y

#연산자 오버로딩
# 새로운 데이터 타입에 필요한 연산자의 행동을 재정의하는 것
# 산술 연산자 오버로딩 예제
def __add__(self, other):
# Point(self) + other
# other 타입을 점검해서 각기 다른 행독을 취하도록
if isinstance(other, Point):
#합산된 객체가 Point
self.x += other.x
self.y += other.y
elif isinstance(other, int):
self.x += other
self.y += other
else:
self += other

return self
#역이항 연산자 : other + Point
def __radd__(self,other):
if isinstance(other, str):
return other + str(self)
elif isinstance(other, int):
self.x += other
self.y += other
else:
self + other
return self

def bound_class_method():
#생성된 인스턴스를 통해 직접 메서드에 접근하는 방법
p = Point()
# bound 방식의 경우, 첫 번째 인자 self는 전달하지 않아도 된다.
p.setX(10)
p.setY(20)

print("Point p: {}, {}".format(p.getX(), p.getY()))
print(p.getX, p.getY)

#bound_class_method()

def unbound_class_method():
#클래스를 통해 우회 접근하는 경우
# 메서드에 부여된 self 인자에 실제 객체의 주소 전달
p = Point()
Point.setX(p,10)
Point.setY(p,20)

print("Point p: {}, {}".format(Point.getX(p),Point.getY(p)))
print(Point.getX, Point.getY)

#unbound_class_method()

def class_member():
p1 = Point()
p2 = Point()

# 클래스 멤버는 모든 인스턴스에서 접근 가능
# 생성 없이도 직접 접근 가능
print("p1 instance_count의 주소:", id(p1.instance_count))
print("p2 instance_count의 주소:", id(p2.instance_count))

#클래스 멤버의 변경
# 공유 메모리 영역으로 활용할 수 있다

Point.instance_count += 1
p1.instance_count += 1
p2.instance_count += 1
print("p2 instance_count:", p2.instance_count)
print("p1 instance_count:", p1.instance_count)

#class_member()

def lifecycle():
# 생성자와 소멸자 테스트
p1 = Point() # 생성자의 기본값이 사용

print(p1)
print("instance_count:", Point.instance_count)

p2 = Point(x=20, y=30)
print("instance_count:", Point.instance_count)

del p2
print("instance_count:", Point.instance_count)

#lifecycle()

def str_repr():
p = Point(10,20)
print(p) # __str__ 호출
print("포인트 p=" + str(p)) # __str__

#repr 함수를 사용하면 __repr__ 문자열을 얻을 수 있다.
print("repr of p:", repr(p))

#eval 함수를 사용하면 파이썬 코드를 테스트 할 수 있다.
#이때 repr로 전달 받은 문자열(개발자용)을 넘겨주면 같은 객체가 복원되어야 한다.
p_repr = eval(repr(p))
print(p_repr, type(p_repr))

str_repr()

def test_overloading():
# 연산자 오버로딩
p = Point(10, 20)
print("P:", p)
p2 = Point(30,40)
print(p)
print(p2)
print("산술 연산자 테스트:", p + p2)
print("Point+ int:", p+20)

print("int + Point:", 20 + p)
# int 입장에서 Point와의 + 불가
# Point 입장에서 int 합산을 재정의 : 역이항
print("포인트 p = " + p)

test_overloading()

반응형
블로그 이미지

꽃꽂이하는개발자

,