spring과 spring boot는 같은 거나 spring boot는 환경설정이 더 편하다.
메서드 체인 방식
으로 수행하므로 [메서드들끼리 연결돼서 통신함]여러 개의 동작(기능)이 한 줄로 수행할 수 있음플러그인
을 제공하므로 이미 개발된 많은 플러그인을 쉽고 빠르게 이용할 수 있음크로스 브라우징
을 제공하므로 브라우저 종류에 상관 없이 동일하게 기능을 수행함CDN 호스트
를 설정해서 사용하는 방법<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="http://code.jquery.com/jquerylatest.min.js"></script>
선택 종류 | 선택자 표현 방법 | 설명 |
---|---|---|
All selector | $("*") | 모든 DOM을 선택합니다. |
ID selector | $("#id") | 해당되는 id를 가지는 DOM을 선택합니다. |
Element selector | $("elementName") | 해당되는 이름을 가지는 DOM을 선택합니다 |
class selector | $(".className") | CSS 중 해당되는 클래스 이름을 가지는 DOM을 선택합니다. |
Multiple selector | $("selector1,selector2, | |
selector3, ...., selectorN") | 해당되는 선택자를 가지는 모든 DOM을 선택합니다. |
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jQuery1</title>
<script src="http://code.jquery.com/jquery-2.2.1.min.js"></script>
<script>
$(document).ready(function(){ //document는 문서 객체, body부분을 말함, ready() : 기능을 구현, DOM 객체 로드되는 이벤트 처리 함수
alert($("#unique2").html()); //$ 일부 태그만 가져와서 처리하고 싶다.
});
</script>
</head>
<body>
<div class="class1">안녕하세요</div>
<div id="unique2">제이쿼리 입니다.</div>
<div id="unique3">
<p>제이쿼리 어렵지 않음!</p>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jQuery2</title>
<script src="http://code.jquery.com/jquery-2.2.1.min.js"></script>
<script>
function addHtml(){
$("#article").html('안녕하세요. 오늘의 뉴스입니다.'+'<br/>');
}
</script>
</head>
<body>
<div>
<p id="article"></p>
</div>
<input type="button" value="추가하기" onClick="addHtml()"/>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jQuery3</title>
<script src="http://code.jquery.com/jquery-2.2.1.min.js"></script>
<script>
function addImage(){
$(".class1").html("<img src='../img/duke.png'>");
}
</script>
</head>
<body>
<div class="class1"></div>
<div class="class2"></div>
<input type="button" value="이미지 추가" onClick="addImage()" />
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jQuery4</title>
<script src="http://code.jquery.com/jquery-2.2.1.min.js"></script>
<script>
function addImage(){
$("div").html("<img src='../img/duke.png'>");
}
</script>
</head>
<body>
<div></div>
<div></div>
<input type="button" value="이미지 추가" onClick="addImage()" />
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jQuery5</title>
<script src="http://code.jquery.com/jquery-2.2.1.min.js"></script>
<script>
function input_process(){
let value = $("#in1").val(); //아이디 값으로 가지고 옴
$("#result").val(value);
}
</script>
</head>
<body>
<input type="text" id="in1" size="10"/>
<input type="button" value="입력하기" onClick="input_process()"/>
<div>
결과 : <br />
<input type="text" id="result" disabled="disabled"/>
</div>
</body>
</html>
기존 웹 페이지의 동작 방식
: 요청 페이지=> 웹 서버 => 결과 페이지ajax 웹 페이지 동작 기술
: 요청페이지=> XMLHttpRequsest => 웹 서버 => 요청 페이지로 반환속성 | 설명 |
---|---|
type | 통신 타입을 설정합니다(post 또는 get 방식으로 선택합니다). |
url | 요청할 url을 설정합니다. |
async | 비동기식으로 처리할지의 여부를 설정합니다(false인 경우 동기식으로 처리합니다). |
data | 서버에 요청할 때 보낼 매개변수를 설정합니다. |
dataType | 응답 받을 데이터 타입을 설정합니다(XML, TEXT, HTML, JSON 등). |
success | 요청 및 응답에 성공했을 때 처리 구문을 설정합니다. |
error | 요청 및 응답에 실패했을 때 처리 구문을 설정합니다. |
complete | 모든 작업을 마친 후 처리 구문을 설정합니다. |
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ajax 연습1</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
function fn_process(){
$.ajax({
type : "get",
datatype : "text",
async : false,
url : "http://localhost:8090/jquery/AjaxTest1",
data : {param : "Hello, jquery"},
success : function(data, textStatus){
$("#message").append(data);
},
error : function(data, textStatus){
alert("서버와 통신 중 에러 발생");
},
complete : function(data, textStatus){
alert("서버와의 통신 완료");
}
});
}
</script>
</head>
<body>
<input type="button" value="전송하기" onClick="fn_process()" /><br><br>
<div id="message"></div>
</body>
</html>
package 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("/AjaxTest1")
public class AjaxTest1 extends HttpServlet {
private static final long serialVersionUID = 1L;
public AjaxTest1() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandler(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandler(request, response);
}
private void doHandler(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
String param = (String)request.getParameter("param"); //객체타입으로 넘어 오기 때문에 형변환
System.out.println("param = "+param);
PrintWriter writer = response.getWriter();
writer.print("안녕 난 난... ajax");
}
}
package 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("/ajaxTest2")
public class AjaxTest2 extends HttpServlet {
private static final long serialVersionUID = 1L;
public AjaxTest2() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandler(request,response);
}
private void doHandler(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html; charset=utf-8");
String result ="";
PrintWriter writer = response.getWriter();
// CDATA 섹션은 " 파서가 마크업이 아닌 문자 데이터로만 해석하도록 표시된 요소 콘텐츠 섹션 "
result ="<main><book>"
+ "<title><![CDATA[초보자를 위한 자바 프로그래밍]]></title>"
+ "<writer><![CDATA[인포북스 저 | 이병승 ]]></writer>"
+ "<image><![CDATA[http://localhost:8090/jquery/img/image1.jpg]]></image>"
+ "</book>"
+ "<book>"
+ "<title><![CDATA[모두의 파이썬]]></title>"
+ "<writer><![CDATA[길벗 저 | 이승찬 ]]></writer>"
+ "<image><![CDATA[http://localhost:8090/jquery/img/image2.jpg]]></image>"
+ "</book></main>";
System.out.println(result);
writer.print(result);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandler(request,response);
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>도서 정보 출력창</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
function fn_process(){
$.ajax({
type :"post",
async:"false",
url:"http://localhost:8090/jquery/ajaxTest2",
dataType:"xml",
success:function(info,textStatus){
$(info).find("book").each(function(){
let title = $(this).find("title").text();
let writer = $(this).find("writer").text();
var image=$(this).find("image").text();
$("#bookInfo").append(
"<p>" +title+ "</p>" +
"<p>" +writer + "</p>"+
"<img src="+image + " />"
);
}); //받은 것에서 book 태그를 찾음
},
error: function(data,textStatus){
alert("에러 발생");
},
complete: function(data,textStatus){
alert("작업 완료");
}
});
}
</script>
</head>
<body>
<div id="bookInfo"></div>
<input type=button value="도서정보 요청" onclick="fn_process()">
</body>
</html>
input type
을 빼먹은 거…그리고 아래 부분 url startNum을 start로 되어 있어서 나는 문제였다.String apiURL = "https://openapi.naver.com/v1/search/blog?query=" + text
+ "&display=10&startNum=" + startNum;
package api;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
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("/NaverSearchAPI.do")
public class SearchAPI extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 1. 인증 정보 설정
String clientId = "네이버에서 발급 받은 거";
String clientSecret = "네이버에서 발급 받은 거";
// 2. 검색 조건 설정
int startNum = 0; // 검색 시작 위치
String text = null; // 검색어
try {
startNum = Integer.parseInt(req.getParameter("startNum"));
String searchText = req.getParameter("keyword");
text = URLEncoder.encode(searchText, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("검색어 인코딩 실패", e);
}
// 3. API URL 조합
String apiURL = "https://openapi.naver.com/v1/search/blog?query=" + text
+ "&display=10&startNum=" + startNum; // json 결과
//String apiURL = "https://openapi.naver.com/v1/search/blog.xml?query=" + text; // xml 결과
// 4. API 호출
Map<String, String> requestHeaders = new HashMap<>();
requestHeaders.put("X-Naver-Client-Id", clientId);
requestHeaders.put("X-Naver-Client-Secret", clientSecret);
String responseBody = get(apiURL, requestHeaders);
// 5. 결과 출력
System.out.println(responseBody); // 콘솔에 출력
resp.setContentType("text/html; charset=utf-8");
resp.getWriter().write(responseBody); // 서블릿에서 즉시 출력
}
private static String get(String apiUrl, Map<String, String> requestHeaders){
HttpURLConnection con = connect(apiUrl);
try {
con.setRequestMethod("GET");
for(Map.Entry<String, String> header :requestHeaders.entrySet()) {
con.setRequestProperty(header.getKey(), header.getValue());
}
int responseCode = con.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { // 정상 호출
return readBody(con.getInputStream());
} else { // 에러 발생
return readBody(con.getErrorStream());
}
} catch (IOException e) {
throw new RuntimeException("API 요청과 응답 실패", e);
} finally {
con.disconnect();
}
}
private static HttpURLConnection connect(String apiUrl){
try {
URL url = new URL(apiUrl);
return (HttpURLConnection)url.openConnection();
} catch (MalformedURLException e) {
throw new RuntimeException("API URL이 잘못되었습니다. : " + apiUrl, e);
} catch (IOException e) {
throw new RuntimeException("연결이 실패했습니다. : " + apiUrl, e);
}
}
private static String readBody(InputStream body){
InputStreamReader streamReader = new InputStreamReader(body);
try (BufferedReader lineReader = new BufferedReader(streamReader)) {
StringBuilder responseBody = new StringBuilder();
String line;
while ((line = lineReader.readLine()) != null) {
responseBody.append(line);
}
return responseBody.toString();
} catch (IOException e) {
throw new RuntimeException("API 응답을 읽는데 실패했습니다.", e);
}
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>검색 API 결과</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
// [검색요청] 버튼 클릭 시 실행할 메서드를 정의
$(function(){
/* id라 #
1. 검색 요청 버튼(id=“searchBtn”)을 눌렀을 때 $.ajax 메서드를 호출하도록 정의 */
$('#searchBtn').click(function(){ //function인 ajax을 예전에 form 태그에서 했던 action을 ajax로 함
$.ajax({
url : "NaverSearchAPI.do", //요청 URL
type : "get", //HTTP 메서드
data : { //data는 json형태로 묶어, 매개변수로 전달할 데이터
keyword : $('#keyword').val(), //검색어, 값을 가져옴
/* 선택된 옵션의 값을 가져와라 */
startNum : $('#startNum option:selected').val() //검색 시작 위치
},
dataType : "json", //응답 데이터 형식
success : sucFuncJson, //요청 성공 시 호출할 메서드 설정
error : errFunc
});
});
});
/*
검색 성공시 결과를 화면에 출력 */
function sucFuncJson(d){
let str ="";
$.each(d.items, function(index, item){ //each = resultset과 같다.
str += "<ul>";
str += "<li>"+ (index+1)+ "</li>";
str += "<li>"+ item.title + "</li>";
str += "<li>"+ item.description + "</li>";
str += "<li>"+ item.bloggername+ "</li>";
str += "<li>"+ item.bloggerlink+ "</li>";
str += "<li>"+ item.postdate+ "</li>";
str += "<li><a href='"+ item.link + "' target='_blank'>바로가기</a></li>";
str +="</ul>"
});
$('#searchResult').html(str);
}
function errFunc(request,status,error){
alert("code"+request.status+"\n"+"message"+request.responseText+"\n"+"error"+error);
}
</script>
<style>
ul{border:2px #cccccc solid}
</style>
</head>
<body>
<div>
<div>
<form id="searchFrm">
한 페이지에 10개씩 출력됨<br/>
<select id="startNum">
<option value="1">1페이지</option>
<option value="2">2페이지</option>
<option value="3">3페이지</option>
<option value="4">4페이지</option>
<option value="5">5페이지</option>
</select>
<input type="text" id="keyword" placeholder="검색어를 입력하시오" />
<input type ="button" id="searchBtn">검색요청</button>
</form>
</div>
<div>
<div class="row" id="searchResult">
결과값 출력
</div>
</div>
</div>
</body>
</html>
제어 역행(IoC, Inversion of Control)
기술을 이용해 애플리케이션 갂의 느슨한의존성 주입(DI, Dependency Injection)
기능을 지원함의존성 주입
: 클래스 객체를 개발자가 코드에서 생성하지 않고 프레임워크가 생성하여 사용하는 방법제어 역행
: 서블릿이나 빈 등을 개발자가 코드에서 생성하지 않고 프레임워크가 직접 수행하는 방법관점 지향
: 핵심 기능 외 부수 기능들을 분리 구현함으로써 모듈성을 증가시키는 방법스프링 기능 | 설명 |
---|---|
Core | 다른 기능과 설정을 분리하기 위한 IoC 기능을 제공합니다. |
Context | 스프링의 기본 기능으로서 애플리케이션의 각 기능을 하는 빈(Bean)에대한 접근 방법을 제공합니다. |
DAO | JDBC 기능을 좀 더 편리하게 사용할 수 있도록 합니다. |
ORM | 하이버네이트나 마이바티스 같은 영속성 관련 프레임워크와 연동된 기능을 제공합니다 |
AOP | 관점 지향 기능을 제공합니다 |
Web | 웹 애플리케이션 개발에 필요한 기능을 제공합니다 |
WebMVC | 스프링에서 MVC 구현에 관련된 기능을 제공합니다 |
사실 별거 아닌걸로 틀려서 부끄러운 마음도 컸다.. 근데 에러 메세지를 보는 방법이라던지 주의사항 같은 걸 알게 되니 부끄럽더라도 공유하고 알고 넘어가는것이 중요한 것 같다.
트위터에서도 봤는데 다른 사람한테 물어보기 부끄러워서 혼자 끙끙 앓다가 나중에는 그냥 타임리밋 걸어두고 안되면 다른 사람한테 물어봄으로 인해 일의 효율이 올라가서 나중에 1주일 휴가쓰고 그랬다고 한다.
부끄럽고 물어보기 무서워도 물어보는 거를 두려워하지 말자!!!