<시험1-애플리케이션 설계 평가자체크리스트>
web.xml에서 TestController.java를 Servlet으로 등록하는 태그를 작성
<servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>com.kh.test.controller.TestController</servlet-class>
</servlet>
위에서 작성한 Servlet 클래스를 mapping하는 태그를 작성
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>/test/test.do</url-pattern>
</servlet-mapping>
기본 생성자와 파라미터 5개 생성자, 모든 필드에 대한 getter/setter를 작성
package com.kh.test.model;
public class Test {
private int seq = 0;
private String writer = null;
private String title = null;
private String content = null;
private String regdate = null;
public Test() {
}
public Test(int seq, String writer, String title, String content, String regdate) {
this.seq = seq;
this.writer = writer;
this.title = title;
this.content = content;
this.regdate = regdate;
}
public int getSeq() {
return seq;
}
public void setSeq(int seq) {
this.seq = seq;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getRegdate() {
return regdate;
}
public void setRegdate(String regdate) {
this.regdate = regdate;
}
}
TEST table과 연결하기 위한 클래스를 작성하고, TEST table의 모든 rows를 리턴하는 메서드를 작성
package com.kh.test.model;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.log4j.Logger;
public class TestDao {
Logger logger = Logger.getLogger(TestDao.class);
public static final String _DRIVER = "oracle.jdbc.driver.OracleDriver";
public static final String _URL = "jdbc:oracle:thin:@192.168.10.3:1521:xe";
public static final String _USER = "kh";
public static final String _PW = "kh";
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
private SqlSessionFactory sqlSessionFactory = null;
SqlSession sqlSession = null;
public TestDao() {
sqlSessionFactory = MyBatisCommonFactory.getSqlSessionFactory();
}
public List<Test> selectList() {
StringBuilder sql = new StringBuilder();
sql.append("SELECT seq, writer, title, content, regdate FROM test");
List<Test> testList = new ArrayList<>();
try {
Class.forName(_DRIVER);
con = DriverManager.getConnection(_URL, _USER, _PW);
pstmt = con.prepareStatement(sql.toString());
rs = pstmt.executeQuery();
Test test = null;
while(rs.next()) {
test = new Test();
test.setSeq(rs.getInt("seq"));
test.setWriter(rs.getString("writer"));
test.setTitle(rs.getString("title"));
test.setContent(rs.getString("content"));
test.setRegdate(rs.getString("regdate"));
testList.add(test);
}
} catch (Exception e) {
logger.info("Exception : "+e.toString());
}
return testList;
}
}
<시험2-애플리케이션 설계서술형(신)>
JSP directive tag 중, jstl 포매팅 라이브러리 사용 구문을 작성
<%@ taglib prefix=”fmt” uri=”<http://java.sun.com/jsp/jstl/fmt”> %>
Web Server와 Web Application Server의 차이점을 서술
Web Server는 HTTP 프로토콜을 기반으로 클라이언트가 웹 브라우저에서 어떠한 요청을 하면 그 요청을 받아 정적 컨텐츠 를 제공하는 서버이다.
WAS는 DB 조회 혹은 다양한 로직 처리를 요구하는 동적 컨텐츠 를 제공하기 위해 만들어진 Application 서버이다.
JSP directive tag 중, jstl core library를 사용할 때 필요한 태그를 서술
<%@ taglib prefix="c" uri="<http://java.sun.com/jsp/jstl/core>" %>
웹 서버프로그램에서 클라이언트 뷰 페이지로 처리된 결과 정보를 전송하려고 할 때 이용할 수 있는 객체를 2개 이상 서술
ServletContext, HttpServletRequest, HttpSession, PrintWriter
Client에서 아래와 같은 form 태그 내 형식을 통해 전송 된 HTTP 요청의 Parameter 정보를 Servlet 클래스의 doGet() 메소드 내에서 변수에 저장하는 구문을 작성
String nickname = request.getParameter("nickname");
String[] hobby = request.getParameter("hobby");
Client에서 아래와 같은 form 태그 내 형식을 통해 전송 된 HTTP 요청의 Parameter 정보를 Servlet 클래스의 doGet() 메소드 내에서 변수에 저장하는 구문을 작성
String phone= request.getParameter("phone");
String[] address = request.getParameter("address");
Servlet Filter의 기능과 용도에 대해 서술
Client로부터 Server로 요청이 들어오기 전에 서블릿을 거쳐서 필터링 하는 것을 서블릿 필터라고 한다.
공통적인 기능들을 서블릿이 호출되기 전에 수행(전처리)되게 하고 싶거나, 서블릿이 호출되고 난 뒤에 수행(후처리) 하고 싶으면 서블릿 필터로 구현하면 된다.
JSP directive tag 중 현재 페이지를 에러 처리용 페이지로 정의하는 구문을 작성
<%@ page isErrorPage=”true” %>
<get post 테스트 - MemberVO.java>
package com.example.demo.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class MemberVO {
private String mem_id = null;
private String mem_pw = null;
private String mem_name = null;
}
<get post 테스트 - RestfulController.java>
package com.example.demo.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.vo.MemberVO;
@RestController
@RequestMapping("/restful/*") // upmu[0]
public class RestfulController {
Logger logger = LoggerFactory.getLogger(RestfulController.class);
// <http://localhost:8000/restful/5>
@GetMapping("{id}")
public String main(@PathVariable int id) {
logger.info("해시값 받아주는 어노테이션 : " + id);
return String.valueOf(id);
}
// <http://localhost:8000/restful/get?mem_Id=kiwi&mem_pw=123&mem_name=키위>
@GetMapping("get") // upmu[1]
public String getTest(MemberVO mVO) {
logger.info(mVO.toString());
return "get요청 : " + mVO.getMem_id() + ", " + mVO.getMem_pw() + ", " + mVO.getMem_name();
}
// postman에서 테스트해야만하며 @RequestBody에 들어갈 값은 Body선택 후
// row 체크하고 반드시 JSON선택해서 JSON 포맷으로 파라미터를 넘겨야함 - 주의할것!
// @RequestBody에 타입을 선언하면 MessageConverter가 대신해줌 - 반드시 JSON포맷으로 넘길 것!
// <http://localhost:8000/restful/post>
@PostMapping("post")
public String postTest(@RequestBody MemberVO mVO) {
logger.info(mVO.toString());
return "post요청 : " + mVO.getMem_id() + ", " + mVO.getMem_pw() + ", " + mVO.getMem_name();
}
}
<이미지 업로드 - index.js>
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { BrowserRouter } from "react-router-dom";
import ImageUploader from "./service/imageUploader";
const imageUploader = new ImageUploader();
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<>
<BrowserRouter>
<App imageUploader={imageUploader} />
</BrowserRouter>
</>
);
<이미지 업로드 - App.jsx>
import { Route, Routes } from 'react-router-dom';
import './App.css';
import LoginPage from './components/auth/LoginPage';
import MemberPage from './components/page/MemberPage';
function App({imageUploader}) {
return (
<>
<Routes>
<Route path="/member" exact={true} element={<MemberPage imageUploader={imageUploader} />} />
</Routes>
</>
);
}
export default App;
<이미지 업로드 - imageUploader.js>
class ImageUploader {
// 여기에는 상태는 없어요
async upload(file) {
//upload했다면 그 URL전달
//아래 수동으로 했던 거 지우고
//return 'file';
const data = new FormData(); // 외부 클라우드 시스템과 연동시에 꼭 필요한 객체
// input type file에서 선택한 파일에대한 정보 담기
data.append("file", file);
// Cloudinary에서 제공하는 서비스를 이용하여 사용자가 선택한 파일에대한 URL정보만
// 제공받아서 처리하므로 upload_preset은 unsigned로 받을 것
data.append("upload_preset", "키"); // unsigned - 인증과정 없이 사용할 때
/*
POST를 이용하니까 POST에 추가하는 데이터 입력하고 fetch를 이용해서 여기 우리가 URL 만들고
POST한 거 데이터를 전송한 다음에 완료가 되면 이제 result를 받아서 result에 있는 것을 json으로
변환해서 리턴해 줄거예요
*/
const result = await fetch(
"<https://api.cloudinary.com/v1_1/키/upload>",
{
method: "POST",
body: data,
}
);
return await result.json();
}
}
export default ImageUploader;
//https://cloudinary.com/documentation/upload_images
<이미지 업로드 - MemberPage.jsx>
import React, { useEffect, useState } from 'react'
import { jsonMemberListDB } from '../../service/dbLogic'
const MemberPage = ({imageUploader}) => {
const [member, setMember] = useState({})
useEffect(()=>{
const memberList = async() => {
const res = await jsonMemberListDB(member)
console.log(res.data)
}
memberList()
},[])
// async는 비동기처리시 사용함
const imgChange = async(event) => {
console.log(event.target.files[0])
// async가 붙은 함수안에서만 await를 사용할 수 있음 - 파일이 업로드될때까지 기다림
const uploaded = await imageUploader.upload(event.target.files[0])
// public_id - 선택한 이미지의 실제 아이디가 아닌 cloudinary에서 부여하는 아이디값
// 이 값으로 실제 이미지 링크 정보가 생성됨
// format은 선택한 파일의 확장자
// url 링크이미지 URL 정보
console.log(`${uploaded.public_id} ${uploaded.format} ${uploaded.url}`)
}
return (
<div>
<h3>회원관리 페이지입니다</h3>
<input type="file" name="mimg" id="mimg" onChange={imgChange} />
</div>
)
}
export default MemberPage
<카카오 api 로그인 - index.js>
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { BrowserRouter } from "react-router-dom";
import ImageUploader from "./service/imageUploader";
const imageUploader = new ImageUploader();
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<>
<BrowserRouter>
<App imageUploader={imageUploader} />
</BrowserRouter>
</>
);
<카카오 api 로그인 - App.jsx>
import { Route, Routes } from 'react-router-dom';
import './App.css';
import LoginPage from './components/auth/LoginPage';
import KakaoRedirectHandler from './components/kakao/KakaoRedirectHandler';
import MemberPage from './components/page/MemberPage';
function App({imageUploader}) {
return (
<>
<Routes>
<Route path='/' exact={true} element={<LoginPage />} />
<Route path='/auth/kakao/callback' exact={true} element={<KakaoRedirectHandler />} />
<Route path="/member" exact={true} element={<MemberPage imageUploader={imageUploader} />} />
</Routes>
</>
);
}
export default App;
<카카오 api 로그인 - LoginPage.jsx>
import React from 'react'
import Image from 'react-bootstrap/Image'
const LoginPage = () => {
const REDIRECT_URI = "http://localhost:3000/auth/kakao/callback"
const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${process.env.REACT_APP_KAKAO_API_KEY}&redirect_uri=${REDIRECT_URI}&response_type=code`
return (
<div>
<a href={KAKAO_AUTH_URL}>
<Image src='/images/kakao/kakao_login_medium_wide.png' />
</a>
</div>
)
}
export default LoginPage
<카카오 api 로그인 - KakaoRedirectHandler.jsx>
import axios from 'axios'
import React from 'react'
import qs from 'qs'
const KakaoRedirectHandler = () => {
// 카카오서버에서 돌려주는 URL 뒤 쿼리스트링 가져오기
// searchParams - URL 내의 GET 디코딩 된 쿼리 매개변수에 접근할 수 있는 URLSearchParams 객체를 반환
let params = new URL(document.location).searchParams;
let code = params.get("code");
console.log(code)
const grant_type = "authorization_code"
const redirect_uri = "http://localhost:3000/auth/kakao/callback"
const getToken = async() => {
const payload = qs.stringify({
grant_type: grant_type,
client_id: process.env.REACT_APP_KAKAO_API_KEY,
redirect_uri: redirect_uri,
code: code
})
try {
const res = await axios.post(
"https://kauth.kakao.com/oauth/token",
payload
)
window.kakao.init(process.env.REACT_APP_KAKAO_API_KEY)
console.log(res.data.access_token)
window.kakao.Auth.setAccessToken(res.data.access_token);
} catch (error) {
console.log(error)
}
}
return (
<div>
{code}
</div>
)
}
export default KakaoRedirectHandler
'국비학원 > 수업기록' 카테고리의 다른 글
국비 지원 개발자 과정_Day79 (0) | 2023.03.22 |
---|---|
국비 지원 개발자 과정_Day78 (0) | 2023.03.21 |
국비 지원 개발자 과정_Day76 (0) | 2023.03.17 |
국비 지원 개발자 과정_Day75 (1) | 2023.03.16 |
국비 지원 개발자 과정_Day74 (1) | 2023.03.15 |
댓글