소비자 인터페이스는 입력을 받아서 그 입력을 소비하고, 결과를 반환하지 않는 작업을 수행하는 데 사용됩니다.
package sec03.lamda;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.IntConsumer;
import java.util.function.ObjIntConsumer;
public class ConsumerDemo {
public static void main(String[] args) {
//Consumer<T> c = t -> { T타입 t 객체를 사용한 후 void를 반환하는 실행문;};
//함수형 인터페이스 구현(accept 구현됨)
Consumer<String> c1 = x -> System.out.println(x.toLowerCase());
c1.accept("Java Function Interface Lamdba");
BiConsumer<String, String> c2 =
(x, y) -> System.out.println(x+":"+y);
c2.accept("Java", "Lambda");
// 함수형 인터페이스 구현, 여러줄로 구현
ObjIntConsumer<String> c3 = (s,x) -> {
int a = Integer.parseInt(s)+x;
System.out.println("문자열과 숫자의 합"+a);
};
c3.accept("100",50);
IntConsumer c4 = x -> System.out.printf("%d * %d = %d\n",x,x,x*x);
IntConsumer c5
= c4.andThen(x -> System.out.printf("%d+10 = %d",x,x+10));
c5.accept(10);
}
}
Consumer<String> c1 = x -> System.out.println(x.toLowerCase());
Consumer<String>
인터페이스를 구현한 람다 표현식 c1을 정의합니다.
c1은 문자열을 입력으로 받아서x.toLowerCase()
를 호출하여 입력을 소문자로 변환한 후 출력합니다.
예를 들어,c1.accept("Java Function Interface Lambda");
를 호출하면 "java function interface lambda"가 출력됩니다.
BiConsumer<String, String> c2 = (x, y) -> System.out.println(x + ":" + y);
BiConsumer<String, String>
인터페이스를 구현한 람다 표현식 c2를 정의합니다.
c2는 두 개의 문자열을 입력으로 받아서 x와 y를 결합한 후 출력합니다.
예를 들어,c2.accept("Java", "Lambda");
를 호출하면 "Java : Lambda"가 출력됩니다.
ObjIntConsumer<String> c3 = (s, x) -> { int a = Integer.parseInt(s) + x; System.out.println("문자열과 숫자의 합: " + a); };
ObjIntConsumer<String>
인터페이스를 구현한 람다 표현식 c3를 정의합니다.
c3는 문자열과 정수를 입력으로 받아서 s를 정수로 변환한 후 x와 더한 결과를 출력합니다.
예를 들어,c3.accept("100", 50);
를 호출하면 "문자열과 숫자의 합: 150"이 출력됩니다.
IntConsumer 인터페이스를 구현한 람다 표현식 c4를 정의합니다.
IntConsumer c4 = x -> System.out.printf("%d * %d = %d", x, x, x * x);
c4는 정수를 입력으로 받아서 해당 정수의 제곱을 출력합니다.
예를 들어,c4.accept(10);
를 호출하면 "10 * 10 = 100"이 출력됩니다.
c4 소비자 후에 추가로 다른 작업을 수행하기 위해 c4.andThen() 메서드를 사용하여 새로운 IntConsumer c5를 정의합니다.
IntConsumer c5 = c4.andThen(x -> System.out.printf("%d + 10 = %d", x, x + 10));
c5는 c4의 동작을 수행한 후에 정수에 10을 더하여 출력합니다.
예를 들어,c5.accept(10);
를 호출하면 "10 * 10 = 100"과 "10 + 10 = 20"이 순서대로 출력됩니다.
공급자 인터페이스는 입력을 받지 않고, 결과를 공급하는 작업을 수행하는 데 사용됩니다.
package sec03.lamda;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.function.DoubleSupplier;
import java.util.function.IntSupplier;
import java.util.function.Supplier;
public class SupplierDemo {
public static void main(String[] args) {
Supplier<String> s1 = () -> "apple";
System.out.println("s1의 실행" + s1.get());
//x라는 정수형 배열을 선언하고 0으로 초기화
int[] x = { 0 }; // 1개짜리 배열
IntSupplier s2 = () -> x[0]++;
for(int i=0; i<3; i++)
System.out.println(s2.getAsInt());
//10까지 수 중 임의로 하나 출력
DoubleSupplier s3 = () -> Math.random() * 10;
System.out.println(s3.getAsDouble());
SimpleDateFormat format
= new SimpleDateFormat("MM월 dd일(E요일) a hh:mm:ss");
Supplier<String> s4 = () -> format.format(new Date());
System.out.println(s4.get());
}
}
Supplier<String> s1 = ( ) -> "apple";
Supplier<String>
인터페이스를 구현한 람다 표현식 s1을 정의합니다.
s1은 "apple" 문자열을 반환합니다.
예를 들어,s1.get( )
을 호출하면 "apple"이 출력됩니다.
크기가 1인 정수형 배열 x를 선언하고 0으로 초기화합니다.
int[ ] x = { 0 };
IntSupplier 인터페이스를 구현한 람다 표현식 s2를 정의합니다.
IntSupplier s2 = ( ) -> x[0]++;
s2는 배열 x의 첫 번째 요소를 반환한 후에 해당 요소를 1 증가시킵니다.
반복문을 통해s2.getAsInt( )
를 세 번 호출하면 x의 첫 번째 요소인 0부터 2까지 순서대로 출력됩니다.
DoubleSupplier 인터페이스를 구현한 람다 표현식 s3를 정의합니다.
DoubleSupplier s3 = ( ) -> Math.random( ) * 10;
s3는 0 이상 10 미만의 임의의 실수를 반환합니다.
예를 들어,s3.getAsDouble( )
을 호출하면 0부터 10 사이의 임의의 실수가 출력됩니다.
형식화된 날짜 및 시간 문자열을 생성하기 위해 SimpleDateFormat 클래스의 인스턴스 format을 생성합니다.
SimpleDateFormat format = new SimpleDateFormat("MM월 dd일(E요일) a hh:mm:ss");
"MM월 dd일(E요일) a hh:mm:ss" 형식으로 날짜 및 시간을 표시합니다.
Supplier<String> s4 = ( ) -> format.format(new Date());
Supplier<String>
인터페이스를 구현한 람다 표현식 s4를 정의합니다.
s4는 현재 날짜와 시간을 format의 형식에 맞게 문자열로 변환하여 반환합니다.
예를 들어,s4.get( )
을 호출하면 "07월 11일(월요일) 오전 10:30:15"과 같은 형식의 현재 날짜 및 시간 문자열이 출력됩니다.
함수 인터페이스는 입력을 받아서 다른 타입으로 변환하거나 다른 값을 반환하는 작업을 수행하는 데 사용됩니다.
package sec03.lamda;
import java.util.function.Function;
import java.util.function.IntToDoubleFunction;
import java.util.function.ToDoubleBiFunction;
public class Function1Demo {
public static void main(String[] args) {
Function<Integer, Integer> add2 = x -> x + 2;
Function<Integer, Integer> mlu2 = x -> x * 2;
System.out.println(add2.apply(3));
System.out.println(mlu2.apply(3));
// add를 하고 mul을 함 -> 3+2 하고나서 결과(5) * 2
System.out.println("3:::"+add2.andThen(mlu2).apply(3));
// mul을 먼저 하고 add -> 3*2 하고나서 결과(6) + 2
System.out.println("4:::"+add2.compose(mlu2).apply(3));
IntToDoubleFunction half = x -> x / 2.0;
System.out.println(half.applyAsDouble(5));
// 숫자가 들어있는 문자열을 double로 읽어서 뒤에 있는 (i*i)를 곱하기 함
ToDoubleBiFunction<String, Integer> circleArea = (s, i)
-> Double.parseDouble(s) * i * i;
double area = circleArea.applyAsDouble("3.14", 5);
System.out.println(area);
}
}
Function<Integer, Integer> 인터페이스를 구현한 람다 표현식 add2를 정의합니다.
Function<Integer, Integer> add2 = x -> x + 2;
add2는 입력으로 정수를 받아 해당 정수에 2를 더한 결과를 반환합니다.
예를 들어, add2.apply(3)을 호출하면 5가 출력됩니다.
Function<Integer, Integer> 인터페이스를 구현한 람다 표현식 mlu2를 정의합니다.
Function<Integer, Integer> mlu2 = x -> x * 2;
mlu2는 입력으로 정수를 받아 해당 정수에 2를 곱한 결과를 반환합니다.
예를 들어, mlu2.apply(3)을 호출하면 6이 출력됩니다.
add2 함수를 먼저 적용한 후에 mlu2 함수를 적용하는 새로운 함수를 생성합니다.
add2.andThen(mlu2)
예를 들어,add2.andThen(mlu2).apply(3)
을 호출하면 먼저 3에 2를 더한 후에 그 결과인 5를 2로 곱한 10이 출력됩니다.
mlu2 함수를 먼저 적용한 후에 add2 함수를 적용하는 새로운 함수를 생성합니다.
add2.compose(mlu2)
예를 들어,add2.compose(mlu2).apply(3)
을 호출하면 먼저 3에 2를 곱한 후에 그 결과인 6에 2를 더한 8이 출력됩니다.
IntToDoubleFunction 인터페이스를 구현한 람다 표현식 half를 정의합니다.
IntToDoubleFunction half = x -> x / 2.0;
half은 정수를 입력으로 받아 해당 정수를 2로 나눈 결과를 실수로 반환합니다.
예를 들어,half.applyAsDouble(5)
를 호출하면 2.5가 출력됩니다.
ToDoubleBiFunction<String, Integer> circleArea = (s, i) -> Double.parseDouble(s) * i * i;
ToDoubleBiFunction<String, Integer>
인터페이스를 구현한 람다 표현식 circleArea를 정의합니다.
circleArea는 문자열과 정수를 입력으로 받아 해당 문자열을 실수로 변환한 후에 정수의 제곱과 곱한 결과를 반환합니다.
예를 들어,circleArea.applyAsDouble("3.14", 5)
를 호출하면 원의 넓이인 78.5가 출력됩니다.
Car 객체 리스트에서 모델과 연식 또는 주행거리를 추출하는 예제
package sec03.lamda;
import java.util.List;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import sec02.lamda.Car;
public class Function2Demo {
public static void main(String[] args) {
Function<Car, String> f1 = c -> c.getModel();
ToIntFunction<Car> f2 = c -> c.getAge();
for (Car car : Car.cars)
System.out.println("("+ f1.apply(car) + ", "+ f2.applyAsInt(car)+")");
System.out.println();
double averageAge = average(Car.cars, c -> c.getAge());
double averageMileage = average(Car.cars, c -> c.getMileage());
System.out.println("평균 연식 = " + averageAge);
System.out.println("평균 주행거리 = " + averageMileage);
}
static public double average(List<Car> cars, ToIntFunction<Car> f) {
double sum = 0.0;
for(Car car : cars)
sum += f.applyAsInt(car);
return sum / cars.size();
}
}
Function<Car, String> f1 = c -> c.getModel();
Function<Car, String>
인터페이스를 구현한 람다 표현식 f1을 정의합니다.
f1은 Car 객체를 입력으로 받아 해당 객체의 모델을 반환합니다.
ToIntFunction<Car> f2 = c -> c.getAge();
ToIntFunction<Car>
인터페이스를 구현한 람다 표현식 f2를 정의합니다.
f2는 Car 객체를 입력으로 받아 해당 객체의 연식을 정수로 반환합니다.
Car 객체 리스트인 Car.cars에 대해 f1과 f2 함수를 적용하여 모델과 연식을 출력합니다.
System.out.println("("+ f1.apply(car) + ", "+ f2.applyAsInt(car)+")");
Car 객체 리스트와 ToIntFunction 함수형 인터페이스를 입력으로 받아 평균을 계산하는 average 메서드를 정의합니다.
double average(List<Car> cars, ToIntFunction<Car> f)
메서드 내에서는f.applyAsInt(car)
를 사용하여 Car 객체의 특정 속성 값을 추출하고, 추출된 값을 모두 더하여 평균을 계산합니다.
계산된 평균 값을 반환합니다.
Car 객체 리스트인
double averageAge = average(Car.cars, c -> c.getAge());
Car.cars와 c.getAge()
를 추출하는 람다 표현식을 average 메서드에 전달하여 평균 연식을 계산합니다.
Car 객체 리스트인
double averageMileage = average(Car.cars, c -> c.getMileage());
Car.cars와 c.getMileage()
를 추출하는 람다 표현식을 average 메서드에 전달하여 평균 주행거리를 계산합니다.
Operator 인터페이스는 입력을 받아서 동일한 타입으로 변환하는 작업을 수행하는 데 사용됩니다.
package sec03.lamda;
import java.util.ArrayList;
import java.util.List;
import java.util.function.IntBinaryOperator;
import java.util.function.IntUnaryOperator;
import java.util.function.UnaryOperator;
public class Operator1Demo {
public static void main (String[] args) {
IntUnaryOperator add2 = x -> x + 2;
System.out.println (add2.applyAsInt (3)) ;
UnaryOperator<Integer> add2again = x -> x + 2;
System.out.println (add2again.apply (3)) ;
IntUnaryOperator mul2 = x -> x * 2;
IntUnaryOperator add2mul2 = add2. andThen (mul2) ;
System.out.printf ("(3 + 2) * 2 = ");
System.out.println (add2mul2.applyAsInt (3)) ;
IntBinaryOperator add = (x, y) -> x + y;
System.out.println (add.applyAsInt (1, 2)) ;
List<Integer> list = new ArrayList<> () ;
list.add (5); list.add (6); list.add (7);
list.replaceAll (e -> e + 10);
System.out.println (list);
}
}
IntUnaryOperator 인터페이스를 구현한 람다 표현식 add2를 정의합니다.
IntUnaryOperator add2 = x -> x + 2;
add2는 정수를 입력으로 받아 해당 정수에 2를 더한 결과를 정수로 반환합니다.
예를 들어,add2.applyAsInt(3)
을 호출하면 5가 출력됩니다.
UnaryOperator<Integer> add2again = x -> x + 2;
UnaryOperator<Integer>
인터페이스를 구현한 람다 표현식 add2again을 정의합니다.
add2again은 정수를 입력으로 받아 해당 정수에 2를 더한 결과를 반환합니다.
예를 들어,add2again.apply(3)
을 호출하면 5가 출력됩니다.
mul2는 정수를 입력으로 받아 해당 정수에 2를 곱한 결과를 정수로 반환합니다.
IntUnaryOperator mul2 = x -> x * 2;
add2 함수를 먼저 적용한 후에 mul2 함수를 적용하는 새로운 함수 add2mul2를 생성합니다.
IntUnaryOperator add2mul2 = add2.andThen(mul2);
예를 들어, (3 + 2) * 2의 결과를 얻기 위해add2.andThen(mul2).applyAsInt(3)
을 호출하면 10이 출력됩니다.
IntBinaryOperator 인터페이스를 구현한 람다 표현식 add를 정의합니다.
IntBinaryOperator add = (x, y) -> x + y;
add는 두 개의 정수를 입력으로 받아 해당 정수들을 더한 결과를 정수로 반환합니다.
예를 들어,add.applyAsInt(1, 2)
을 호출하면 3이 출력됩니다.
List<Integer> list = new ArrayList<>();
List<Integer>
타입의 list 객체를 생성합니다.
list에 포함된 각 요소에 대해 e -> e + 10 람다 표현식을 적용하여 요소를 변경합니다.
list.replaceAll(e -> e + 10);
예를 들어, list에 [5, 6, 7]이 포함되어 있을 경우, replaceAll 메서드를 호출한 후에 list는 [15, 16, 17]로 변경됩니다.
package sec03.lamda;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.BinaryOperator;
import java.util.function.UnaryOperator;
import sec02.lamda.Car;
public class Operator2Demo {
public static void main(String[] args) {
Comparator<Integer> compatator = (a, b) -> a - b;
BinaryOperator<Integer> o1 = BinaryOperator.maxBy(compatator);
System.out.println (o1.apply(10, 5));
System.out.println (o1.apply(20, 25));
BinaryOperator<Integer> o2 = BinaryOperator.minBy(compatator);
System.out.println (o2.apply(10, 5));
System.out.println (o2.apply(20, 25));
List<Car> newCars = remodeling(Car.cars, c -> new Car("뉴" +
c.getModel(), c.isGasoline(), c.getAge(), c.getMileage()));
System.out.println(newCars);
}
static public List<Car> remodeling(List<Car> cars, UnaryOperator<Car> o){
List<Car> result = new ArrayList<>();
for (Car car : Car.cars)
result.add(o.apply(car));
return result;
}
}
Comparator<Integer> comparator = (a, b) -> a - b;
Comparator<Integer>
인터페이스를 구현한 람다 표현식 comparator를 정의합니다.
comparator는 두 개의 정수를 입력으로 받아 차이를 계산하여 비교합니다.
BinaryOperator<Integer> o1 = BinaryOperator.maxBy(comparator);
BinaryOperator.maxBy()
메서드를 사용하여 최댓값을 계산하는 o1을 정의합니다.
o1.apply(10, 5)를 호출하면 10이 출력되며, o1.apply(20, 25)를 호출하면 25가 출력됩니다.
BinaryOperator<Integer> o2 = BinaryOperator.minBy(comparator);
BinaryOperator.minBy()
메서드를 사용하여 최솟값을 계산하는 o2를 정의합니다.
o2.apply(10, 5)를 호출하면 5가 출력되며, o2.apply(20, 25)를 호출하면 20이 출력됩니다.
List<Car> newCars = remodeling(Car.cars, c -> new Car("뉴" + c.getModel(), c.isGasoline(), c.getAge(), c.getMileage()));
remodeling()
메서드를 사용하여 Car 객체 리스트를 리모델링하여 새로운 Car 객체 리스트인 newCars를 생성합니다.
remodeling() 메서드는 Car 객체 리스트와 UnaryOperator 함수형 인터페이스를 입력으로 받습니다.
c -> new Car("뉴" + c.getModel(), c.isGasoline(), c.getAge(), c.getMileage())는 Car 객체를 입력으로 받아 해당 객체를 변경하여 새로운 Car 객체를 반환하는 람다 표현식입니다.
newCars는 리모델링된 Car 객체 리스트입니다.
static public List<Car> remodeling(List<Car> cars, UnaryOperator<Car> o)
remodeling()
메서드는 Car 객체 리스트와 UnaryOperator 함수형 인터페이스를 입력으로 받아 Car 객체 리스트를 리모델링하는 메서드입니다.
메서드 내에서는 o.apply(car)를 사용하여 Car 객체에 대해 UnaryOperator 함수를 적용하고, 결과로 얻은 새로운 Car 객체를 result 리스트에 추가합니다.
최종적으로 result 리스트를 반환합니다.
Car 객체 리스트에서 모델 또는 주행거리를 기준으로 정렬을 수행하는 예제
package sec03.lamda;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import sec02.lamda.Car;
public class Comparator1Demo {
public static void main(String[] args) {
// 0번부터 3개까지 리스트
List<Car> list = Car.cars.subList(0, 3);
Car[] cars = list.toArray(new Car[3]);
Comparator<Car> modelComparator
= Comparator.comparing(Car::getModel);
System.out.println(Arrays.toString(cars));
// 모델로 sort(가나다순)
Arrays.sort(cars, modelComparator);
System.out.println(Arrays.toString(cars));
// 모데로 sort (역순)
Arrays.sort(cars, modelComparator.reversed());
System.out.println(Arrays.toString(cars));
// Mileage를 기준으로 비교(작은 것부터 앞으로) a-b 와 같은 방식으로 비교
Arrays.sort(cars, Comparator.comparingInt(Car::getMileage));
System.out.println(Arrays.toString(cars));
// 역순(b-a) 큰것이 앞>>>>뒤
Arrays.sort(cars, Comparator.comparing(Car::getMileage, (a,b) -> b-a));
System.out.println(Arrays.toString(cars));
}
}
Car.cars에서 0번부터 2번 인덱스까지의 요소로 구성된 부분 리스트 list를 생성합니다.
List<Car> list = Car.cars.subList(0, 3);
list를 Car 객체 배열로 변환하여 cars에 저장합니다.
Car[ ] cars = list.toArray(new Car[3]);
Comparator<Car> modelComparator = Comparator.comparing(Car::getModel);
Comparator.comparing()
메서드를 사용하여 모델을 기준으로 비교하는 modelComparator를 생성합니다.
Car::getModel은 Car 객체에서 모델을 추출하는 메서드 레퍼런스입니다.
modelComparator를 사용하여 cars 배열을 모델을 기준으로 오름차순 정렬합니다.
Arrays.sort(cars, modelComparator);
Arrays.sort(cars, modelComparator.reversed());
modelComparator.reversed()
를 사용하여 cars 배열을 모델을 기준으로 내림차순 정렬합니다.
Arrays.sort(cars, Comparator.comparingInt(Car::getMileage));
Comparator.comparingInt()
메서드를 사용하여 주행거리를 기준으로 작은 값부터 정렬하는 Comparator를 생성합니다.
Car::getMileage는 Car 객체에서 주행거리를 추출하는 메서드 레퍼런스입니다.
Arrays.sort(cars, Comparator.comparing(Car::getMileage, (a,b) -> b-a));
Comparator.comparing()
메서드와 람다 표현식 (a,b) -> b-a를 사용하여 주행거리를 기준으로 큰 값부터 정렬하는 Comparator를 생성합니다.
첫 번째 정렬은 모델을 기준으로 오름차순으로 정렬하고, 두 번째 정렬은 모델을 기준으로 내림차순으로 정렬합니다. 세 번째 정렬은 주행거리를 기준으로 작은 값부터 정렬하고, 네 번째 정렬은 주행거리를 기준으로 큰 값부터 정렬합니다.
package sec01.stream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class StreamDemo {
public static void main (String[] args) {
// 컬랙션
List<Integer> list = new ArrayList<> ();
Random r = new Random ();
// 10번은 돌고
for (int i = 0; i < 10; i++)
list.add(r.nextInt (30));
System.out.println("0:::: "+list);
List<Integer> gt10 = new ArrayList<> ();
for (int i: list)
if (i > 10)
gt10.add (i);
Collections. sort (gt10);
System.out.println("1:::: "+gt10);
// stream 방식
System.out.print("2:::: ");
list.stream().filter(i -> i>10).sorted()
.forEach(x -> System.out.print(x + " "));
}
}
Integer 타입의 list 객체를 생성합니다.
List<Integer> list = new ArrayList<>();
난수를 생성하기 위해 Random 객체 r을 생성합니다.
Random r = new Random();
0부터 29 사이의 난수를 list에 추가합니다.
list.add(r.nextInt(30));
초기 list의 값을 출력합니다.
System.out.println("0:::: " + list);
10보다 큰 숫자를 저장하기 위한 gt10 리스트를 생성합니다.
List<Integer> gt10 = new ArrayList<>();
list의 요소를 하나씩 가져오는 향상된 for 루프를 사용합니다.
for (int i : list)
현재 요소가 10보다 큰지 확인합니다.
if (i > 10)
10보다 큰 요소를 gt10 리스트에 추가합니다.
gt10.add(i);
gt10 리스트를 정렬합니다.
Collections.sort(gt10);
list를 스트림으로 변환하여 처리합니다.
list.stream().filter(i -> i > 10).sorted().forEach(x -> System.out.print(x + " "));
10보다 큰 요소만 필터링합니다.
filter(i -> i > 10):
요소를 정렬합니다.
sorted():
각 요소를 출력합니다.
forEach(x -> System.out.print(x + " ")):
<title>Ajax 연습</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
//id="listButton"인 태그에 click하면 function getMemberList()실행
$('#listButton').click(getMemberList);
});
function getMemberList(){
$.ajax({
url:"./list.jsp", //list.jsp에 Ajax요청
success:function(data){ // 잘 갔다왔다면 성공
alert(data.result);
},
error:function(request, status, error){
alert(2+"::"+request.status);
alert(2+"::"+request.reponseText);
alert(2+"::"+request.status);
}
});
}
</script>
----------list.jsp file----------
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="org.json.simple.JSONObject" %>
<%
// Class. forName ("com.mysql.cj.jdbc.Driver");
// System.out. println ("여기왔다: : "+1);
JSONObject jobj = new JSONObject ();
jobj.put("result", "잘다녀옴");
response.setContentType ("application/json");
out.print(jobj.toJSONString()); // json 형식으로 출력
%>
jQuery 라이브러리를 사용하기 위해 CDN에서 jQuery를 가져옵니다.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
HTML 문서가 로드되면 실행될 함수를 정의합니다.
$(document).ready(function(){ ... });
listButton이라는 id를 가진 태그를 클릭하면 getMemberList 함수가 실행되도록 설정합니다.
$('#listButton').click(getMemberList);
getMemberList 함수는 Ajax를 사용하여 서버에서 데이터를 가져오는 요청을 보냅니다.
function getMemberList() { ... }
url: "./list.jsp": list.jsp로 Ajax 요청을 보냅니다.
success: function(data) { ... }:
요청이 성공하면 서버로부터 받은 데이터를 처리하는 함수입니다. 받은 데이터의 result 값을 alert로 출력합니다.
error: function(request, status, error) { ... }:
요청이 실패하면 에러 상태와 에러 메시지를 alert로 출력합니다.- list.jsp 파일은
JSONObject를 사용하여 JSON 형식의 데이터를 생성합니다.
response.setContentType("application/json"):
응답의 content type을 JSON으로 설정합니다.
out.print(jobj.toJSONString()):
JSON 형식의 데이터를 출력합니다.이 코드는 listButton이 클릭되면 list.jsp로 Ajax 요청을 보내고, list.jsp에서는 JSON 형식의 데이터를 생성하여 응답합니다.
이후 응답 데이터는 success 콜백 함수에서 처리됩니다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="/webBoard/member">
<input type="submit" value="전송">
</form>
</body>
</html>
----------
<body>
여기는 main
</body>
----------
package member;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class memberController
*/
@WebServlet("/member")
public class MemberController extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public MemberController() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// response.getWriter().append("Served at: ").append(request.getContextPath());
requestPro(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
requestPro(request, response);
}
public void requestPro(HttpServletRequest request, HttpServletResponse resonse)
throws ServletException, IOException {
String view = "member/main.jsp";
//들어오면 원하는 기능에 해당되는 (비지니스 로직)파일로 보내면 일을하고 돌아와서 view로 리턴
// view로 호출해서 전달하기 위한 객체
RequestDispatcher dispatcher =request.getRequestDispatcher(view);
dispatcher.forward(request, resonse);
}
}
member 경로로 들어오는 HTTP 요청을 처리하기 위해 MemberController 서블릿을 매핑합니다.
@WebServlet("/member")
GET 요청을 처리하는 메서드입니다.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
requestPro(request, response) 메서드를 호출하여 요청을 처리합니다.
POST 요청을 처리하는 메서드입니다.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
requestPro(request, response) 메서드를 호출하여 요청을 처리합니다.
비즈니스 로직을 처리하는 메서드입니다.
public void requestPro(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
view 변수에 "member/main.jsp" 값을 할당합니다.
RequestDispatcher를 생성하여 view로 요청을 전달합니다.
dispatcher.forward(request, response)
를 사용하여 요청을 전달하고 응답을 받습니다.
-----JSP 파일-----
JSP 파일에서는 HTML과 Java 코드를 혼합하여 웹 페이지를 작성합니다.
<form action="/webBoard/member">
을 사용하여 /webBoard/member 경로로 폼 데이터를 전송하는 폼을 생성합니다.
<input type="submit" value="전송">
을 사용하여 전송 버튼을 생성합니다.
이 코드는 "/member" 경로로 들어오는 GET 또는 POST 요청을 MemberController 서블릿으로 처리합니다.
requestPro()
메서드에서는 비즈니스 로직을 처리한 후 "member/main.jsp"를 보여주는 뷰로 요청을 전달합니다.
----------LoginAction----------
package member;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginAction implements CommandAction {
@Override
public String requestPro(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
// 데이터베이스를 통해서 로그인이 맞는지 확인하고
// 회원이 맞으면 main.jsp 보내고
// 회원이 아니면 다시 로그인으로 보내기
System.out.println("loginAction 진입");
return "member/login.jsp";
}
}
----------CommandAction file----------
package member;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// 공통된 메소드를 쓰게 하려고 인터페이스 생성
public interface CommandAction {
public String requestPro(HttpServletRequest request,
HttpServletResponse response)throws ServletException,
IOException;
}
----------memberController----------
package member;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class memberController
*/
// @WebServlet("/member")
@WebServlet(
name = "MemberController",
urlPatterns = {"*.do"})
public class MemberController extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public MemberController() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// response.getWriter().append("Served at: ").append(request.getContextPath());
requestPro(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
requestPro(request, response);
}
public void requestPro(HttpServletRequest request, HttpServletResponse resonse)
throws ServletException, IOException {
String view = "member/main.jsp";
CommandAction com = null;
//해당 request를 받아서 해당 업무로직을 생성하고 호출할거임.
com = new LoginAction();
view = com.requestPro(request, resonse);
System.out.println(view);
//들어오면 원하는 기능에 해당되는 (비지니스 로직)파일로 보내면 일을하고 돌아와서 view로 리턴
// view로 호출해서 전달하기 위한 객체
RequestDispatcher dispatcher =request.getRequestDispatcher(view);
dispatcher.forward(request, resonse);
}
}
LoginAction 클래스
CommandAction 인터페이스를 구현한 클래스입니다.
requestPro(HttpServletRequest request, HttpServletResponse response)
메서드를 오버라이드하여 로그인 동작을 처리합니다.
데이터베이스를 통해 로그인 정보를 확인하고, 회원인 경우 "member/main.jsp"를 반환하고 회원이 아닌 경우 "member/login.jsp"를 반환합니다.
CommandAction 인터페이스
공통된 메소드를 사용하기 위해 인터페이스를 생성합니다.
requestPro(HttpServletRequest request, HttpServletResponse response)
메서드를 정의합니다.
MemberController 서블릿
doGet()과 doPost()
메서드에서requestPro()
메서드를 호출하여 요청을 처리합니다.
requestPro(HttpServletRequest request, HttpServletResponse response)
메서드에서는 해당하는 업무로직을 생성하고 호출합니다.
현재 예제에서는 로그인 동작을 처리하기 위해 LoginAction을 생성하고 호출합니다.
com.requestPro(request, response)
를 통해 로그인 동작을 처리하고 반환된 뷰 경로를 view 변수에 저장합니다.
RequestDispatcher를 생성하여 view로 요청을 전달하고 응답합니다.
login.jsp와 main.jsp는 웹 페이지의 일부분을 구성하는 JSP 파일입니다.
이 코드는 회원 로그인 동작을 처리하는 LoginAction 클래스와 로직을 관리하는 MemberController 서블릿을 포함합니다.
MemberController에서는 요청에 따라 적절한 로직을 호출하여 처리하고, 로직에서 반환된 뷰 경로를 기반으로 해당하는 JSP 파일을 호출하여 응답합니다.
login.do
package member;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class memberController
*/
// @WebServlet("/member")
@WebServlet(
name = "MemberController",
urlPatterns = {"*.do"})
public class MemberController extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public MemberController() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// response.getWriter().append("Served at: ").append(request.getContextPath());
requestPro(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
requestPro(request, response);
}
public void requestPro(HttpServletRequest request, HttpServletResponse resonse)
throws ServletException, IOException {
String view = null;
CommandAction com = null;
//해당 request를 받아서 해당 업무로직을 생성하고 호출할거임.
String command = request.getRequestURI();
if(command.indexOf(request.getContextPath())==0) {
command = command.substring(request.getContextPath().length());
}
System.out.println("comand ::: "+command);
switch(command) {
case "login.do":{
com = new LoginAction();
view = com.requestPro(request, resonse);
break;
}
default:view = "member/main.jsp";
}
// com = new LoginAction();
// view = com.requestPro(request, resonse);
// System.out.println(view);
//들어오면 원하는 기능에 해당되는 (비지니스 로직)파일로 보내면 일을하고 돌아와서 view로 리턴
// view로 호출해서 전달하기 위한 객체
RequestDispatcher dispatcher =request.getRequestDispatcher(view);
dispatcher.forward(request, resonse);
}
}
수정
String view = null;
CommandAction com = null;
주석처리
// com = new LoginAction();
// view = com.requestPro(request, resonse);
// System.out.println(view);
추가
String command = request.getRequestURI();
if(command.indexOf(request.getContextPath())==0) {
command = command.substring(request.getContextPath().length());
}
System.out.println("comand ::: "+command);
switch(command) {
case "login.do":{
com = new LoginAction();
view = com.requestPro(request, resonse);
break;
}
case "/loginAction.do":{
com = new LoginProAction();
view = com.requestPro(request, resonse);
}
default:view = "member/main.jsp";
}
String view = null;과 CommandAction com = null;
을 추가.사용하여 요청의 URI를 가져옵니다.
request.getRequestURI()
사용하여 컨텍스트 경로와 일치하는지 확인합니다.
command.indexOf(request.getContextPath())==0
사용하여 컨텍스트 경로 이후의 요청 경로를 가져옵니다.
command.substring(request.getContextPath().length())
사용하여 요청 경로를 출력합니다.
System.out.println("comand ::: " + command);
switch 문을 사용하여 요청에 따른 작업을 처리합니다.
case "login.do":
에서 LoginAction을 생성하고com.requestPro(request, response)
를 호출하여 로그인 동작을 처리하고 반환된 뷰 경로를 view 변수에 저장합니다.
case "/loginAction.do":
에서 LoginProAction을 생성하고com.requestPro(request, response)
를 호출하여 로그인 프로세스 동작을 처리하고 반환된 뷰 경로를 view 변수에 저장합니다.
default에서는 기본적으로 "member/main.jsp"를 view 변수에 저장합니다.
을 사용하여 view로 요청을 전달합니다.
RequestDispatcher dispatcher = request.getRequestDispatcher(view);
이렇게 수정된 코드는 요청에 따라 다양한 작업을 처리할 수 있도록 확장되었습니다.
/login.do 경로로 들어오면 LoginAction을 실행하여 로그인 동작을 처리하고
/loginAction.do 경로로 들어오면 LoginProAction을 실행하여 로그인 프로세스 동작을 처리합니다.
기본적으로는 "member/main.jsp"를 뷰로 사용합니다.
로그인 페이지(login.jsp), 로그인 처리 액션(LoginProAction), 데이터베이스 접근을 담당하는 DAO(MemberDAO), 그리고 로그인 관련 업무 로직(LoginAction)을 포함하고 있습니다. MemberController 클래스는 요청에 따라 적절한 로직을 선택하여 처리하며, 결과에 따라 뷰를 전달합니다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>login</title>
<style type="text/css">
*{margin: 0 auto;}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
<script type="text/javascript">
$().ready(function(){
});
</script>
</head>
<body>
<form action="/webBoard/loginAction.do">
<table>
<tbody>
<tr>
<th>아이디</th>
<td><input type="text" name="id" size="10" required="required"></td>
</tr>
<tr>
<th>비밀번호</th>
<td><input type="password" name="passwd" size="10" required="required"></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="전송">
</td>
</tr>
</tbody>
</table>
</form>
</body>
</html>
----------LoginProAction----------
package member;
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import member.model.MemberDAO;
public class LoginProAction implements CommandAction {
@Override
public String requestPro(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String id = request.getParameter("id");
String passwd = request.getParameter("passwd");
System.out.println("id:::"+id);
System.out.println("passwd:::"+passwd);
// 데이터베이스에 접근해서 결과를 받아오게...DAO
/* 데이터베이스 일하는 객체 생성해서 거기에서 내가 시키고 싶은 메소드 호출
* DAO 객체(인스턴스)를 얻고, 거기에서 아이디와 비밀번호가 맞는지 확인하는 메소드 호출*/
String view = null;
MemberDAO dao = MemberDAO.getInstance();
// 아이디, 비밀번호 맞는지 확인해, 라는 메소드를 실행
try {
boolean result = dao.loginAction(id, passwd);
if(result) view = "member/main.jsp";
else view = "member/login.jsp";
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return view;
}
}
----------MemberDAO----------
package member.model;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class MemberDAO {
//인스턴스 객체를 선언 private
private static MemberDAO instance = new MemberDAO();
private Connection getConnection() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn=
DriverManager
.getConnection("jdbc:mysql://localhost:3306/boarddb","root","1234");
return conn;
}
private MemberDAO() {}
public static MemberDAO getInstance() {
return instance;
}
public boolean loginAction(String id, String passwd)
throws ClassNotFoundException, SQLException {
boolean result = false;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
String sql = "select count(*) from member where id=? and passwd=?";
conn = getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, id);
pstmt.setString(2, passwd);
rs = pstmt.executeQuery();
if(rs.next()) {// 결과를 받아온게 있으면
int r = rs.getInt(1);
if(r==0) result = false;
else if (r==1) result = true;
}
}catch(Exception e) {
System.out.println(e.getMessage());
}finally {
if(rs!=null)rs.close();
if(pstmt!=null)pstmt.close();
if(conn!=null)conn.close();
}
return result;
}
}
----------LoginAction----------
package member;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginAction implements CommandAction {
@Override
public String requestPro(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
// 데이터베이스를 통해서 로그인이 맞는지 확인하고
// 회원이 맞으면 main.jsp 보내고
// 회원이 아니면 다시 로그인으로 보내기
System.out.println("loginAction 진입");
return "member/main.jsp";
}
}
----------memberController----------
package member;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class memberController
*/
// @WebServlet("/member")
@WebServlet(
name = "MemberController",
urlPatterns = {"*.do"})
public class MemberController extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public MemberController() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// response.getWriter().append("Served at: ").append(request.getContextPath());
requestPro(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
requestPro(request, response);
}
public void requestPro(HttpServletRequest request, HttpServletResponse resonse)
throws ServletException, IOException {
String view = null;
CommandAction com = null;
//해당 request를 받아서 해당 업무로직을 생성하고 호출할거임.
String command = request.getRequestURI();
if(command.indexOf(request.getContextPath())==0) {
command = command.substring(request.getContextPath().length());
}
System.out.println("command ::: "+command);
switch(command) {
case "/login.do":{ //아이디, 패스워드 받기 위해서 화면만 띄우기
com = new LoginAction();
view = com.requestPro(request, resonse);
break;
}
case "/loginAction.do":{//id,pw검증
com = new LoginProAction();
view = com.requestPro(request, resonse);
break;
}
default:view = "member/main.jsp";
}
// com = new LoginAction();
// view = com.requestPro(request, resonse);
// System.out.println(view);
//들어오면 원하는 기능에 해당되는 (비지니스 로직)파일로 보내면 일을하고 돌아와서 view로 리턴
// view로 호출해서 전달하기 위한 객체
RequestDispatcher dispatcher =request.getRequestDispatcher(view);
dispatcher.forward(request, resonse);
}
}
login.jsp
로그인 페이지를 구성하는 HTML과 JavaScript 코드가 포함되어 있습니다.
아이디와 비밀번호를 입력하는 폼과 전송 버튼이 있으며, 입력한 데이터를 /webBoard/loginAction.do로 전송합니다.
LoginProAction 클래스
CommandAction 인터페이스를 구현한 클래스로, 로그인 액션을 처리합니다.
requestPro 메서드는 HttpServletRequest와 HttpServletResponse를 매개변수로 받아 로그인 처리를 수행합니다.
전달받은 아이디와 비밀번호를 데이터베이스에 접근하여 확인하고, 결과에 따라 member/main.jsp 또는 member/login.jsp로 리턴합니다.
MemberDAO 클래스 => 데이터베이스와 관련된 작업을 수행하는 클래스입니다.
싱글톤 패턴을 사용하여 인스턴스를 생성하고, getInstance 메서드를 통해 인스턴스를 반환합니다.
getConnection 메서드는 데이터베이스 연결을 수행합니다.
loginAction 메서드는 아이디와 비밀번호를 매개변수로 받아 데이터베이스에서 확인한 후 결과를 반환합니다.
LoginAction 클래스
CommandAction 인터페이스를 구현한 클래스로, 로그인 액션을 처리합니다.
requestPro 메서드는 HttpServletRequest와 HttpServletResponse를 매개변수로 받아 로그인 처리를 수행합니다.
현재 구현은 로그인이 맞는지 확인하는 로직이 없으므로 그저 "loginAction 진입"을 출력하고 member/main.jsp를 리턴합니다.
MemberController 클래스 => HTTP 요청을 처리하는 서블릿 클래스입니다.
GET 및 POST 요청을 처리하기 위해 doGet 및 doPost 메서드를 오버라이드합니다.
requestPro 메서드는 HttpServletRequest와 HttpServletResponse를 매개변수로 받아 해당 업무로직을 생성하고 호출합니다.
요청 URI를 분석하여 적절한 업무 로직(LoginAction 또는 LoginProAction)을 선택하고, 해당 로직의 requestPro 메서드를 호출합니다.
업무 로직의 처리 결과에 따라 member/main.jsp 또는 기본 member/main.jsp로 리턴합니다.
이렇게 수정된 코드는 로그인 폼을 구성하고, 입력된 아이디와 비밀번호를 데이터베이스에서 확인하여 로그인 기능을 구현합니다.