JSP/개념정리

비동기 처리

Itchild 2024. 4. 29. 11:55
728x90
반응형

 

페이지의 이동 없이(= 화면의 깜빡임 없이) 처리 되는것을 비동기 처리이다.

사진 바꾸는 실습, 빈 하트 이미지나 아이콘이 빨간하트 꽉찬 하트로 바뀌는 경우(찜하기) 를 많이 쓰기 때문에

이러한 기능들이 비동기 처리 된 것인데 자바스크립트의 Ajax 메서드로 비동기 처리 구현이 가능하다.

 

기본 형식 - Ajax 메서드

얘를 on click 했을 때 함수 실행 시켜줘 (기본 형식)
$ ( ).on("click" , function() {

   $.ajax( {           

         url: 
         type:
         success:
         error: 
    } );
});
 

 

실습 - 비동기 처리

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ajax 실습</title>
<style type="text/css">
   img {
      cursor: pointer;
   }
</style>
</head>
<body>

<img id="photo" alt="실습용 이미지" src="">

<script src="https://code.jquery.com/jquery-3.7.0.min.js" integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" crossorigin="anonymous"></script>
<script type="text/javascript">
   $("#photo").prop("src","images/보노보노.jpg");
   
   $("#photo").on("click",function(){
      $.ajax({
         url: 'test.do',
         type: 'POST',
         success: function(result){
            console.log('result ['+result+']');
            if(result=='apple'){
               $("#photo").prop("src","images/짱구.jpg");
            }else{
            	$("#photo").prop("src","images/보노보노.jpg")
            }
         },
         error: function(error){
            alert('error ['+error+']');
         }
      });
   });
</script>

</body>
</html>
 

jQuery의 .prop() 메서드는 지정한 선택자를 가진 첫번째 요소의 속성값을 가져오거나 속성값을 추가한다. 주의할 점은 HTML 입장에서의 속성(attribute)이 아닌 JavaScript 입장에서의 속성(property)이라는 것이다.

 

  • 어떤 요청을 할건지(url) - "test.do"
  • 어떤 타입을 할건지(type) - "post"
  • (생략 되었지만) dataType - "json"

==> Ajax 메서드는 보통 json 타입이기 때문에 생략했다면 json타입이라고 인식한다.

  • 성공했다면 무슨 함수를 실행 시킬 건지 받아올 결과 값을 함수인자에 작성

뭘 받아올지를 콘솔에 띄워볼 예정

  • 실패했다면 무슨 함수를 실행 시킬 건지

alert 창 띄워 보기

 


그렇다면 우리가 생각해볼수 있는 질문

 

 

Q ) 아무런 변화가 없는데 왜 에러가 아닌가요 ?

에러가 난적이 없다. 프론트 컨트롤러로 갈 수 있다. 반환값에 포함되지 않기 때문에 에러가 아닙니다.

alert창이 안떴으니 에러가 아니다. *.do 요청을 맵핑 하고 있다. 프론트 컨트롤러 탔다.

Ajax는 reponse.sendRedirect server 를 거치지 않아 Ajax 자체가 반환으로 넘어 왔다는 점.

(server를 거치진 않지만 MVC 를 왔다갔다 한다. DB에도 접근하여 값을 가져옴 )


package controller;

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("/test.do")
public class TestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    
    public TestServlet() {
        super();
    }
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		      System.out.println("ajax 로그 : "+request.getParameter("banana"));
		      PrintWriter out=response.getWriter();
		      out.print("apple");
		      out.print("banana");
		   }
		
	}


 

비동기 전용 서블릿 파일을 만들어 연결.

서블릿파일은 내장객체가 없어서 직접 꺼내줘야 한다.(선언해야한다.)

PrintWriter out = response.getWriter();

이제 "out" 이라는 내장객체를 쓸 수 있음

Ajax 메서드 success에 들어갈 인자 ( result )값으로 보내준 "apple" , "banana"

 

그래서, 만약에 이게 result 인 상태야 ?

그러면 이미지를 이걸로 바꿔줘. 빈 하트가 꽉찬 하트로 바뀌는 느낌

 

  • 몇번째 게시글인지도 보내야 되는데 어떻게 해야 되나요 ???

url 로 보내면 된다.

ex) url: 'test.do' 여기에 !! → url: 'test.do?banana=1',

 


비동기 처리 과정 중 만난 에러

 

undefined : 찾을 수 없음

 

✔️ Ajax 메서드의 기본 개념

Ajax 메서드에서 일반적으로 사용되는 데이터 타입들은 다음과 같다:

 

1. `text`: 데이터를 문자열로 주고받을 때 사용합니다. 이 형식은 서버가 일반 텍스트를 응답하거나 클라이언트가 텍스트를 서버에게 보낼 때 사용됩니다.

 

2. `json`: 데이터를 JSON 형식으로 주고받을 때 사용합니다. JSON은 JavaScript Object Notation의 약자로, 데이터를 구조화하여 표현하는 형식입니다. 주로 복잡한 데이터 구조를 주고받을 때 사용되며, 객체와 배열을 포함할 수 있습니다.

 

3. `xml`: 데이터를 XML 형식으로 주고받을 때 사용합니다. XML은 eXtensible Markup Language의 약자로, JSON과 비슷하게 데이터를 구조화하여 표현하는 형식입니다. 예전에는 많이 사용되었지만, 최근에는 JSON이 더 많이 사용됩니다.

 

4. `html`: 데이터를 HTML 형식으로 주고받을 때 사용합니다. 주로 동적인 웹 페이지를 구현할 때 사용됩니다.

 

5. `script`: 데이터를 JavaScript 코드로 주고받을 때 사용합니다. 일반적으로 웹 페이지에서 동적으로 스크립트를 실행하고자 할 때 사용됩니다.

 

6. `jsonp`: JSONP(JSON with Padding)는 JSON 데이터를 Cross-Origin Resource Sharing (CORS) 이슈를 우회하기 위해 사용되는 기법으로, 서버에서 JSON 데이터를 JavaScript 코드로 감싸서 응답합니다.

 

일반적으로 가장 많이 사용되는 데이터 타입은 `text`와 `json`입니다. 데이터 타입은 서버와 클라이언트 사이의 협의에 따라 설정하며, 주로 JSON 데이터를 주고받는 것이 일반적입니다.

 

 

✔️ Ajax() 와 비동기처리 전용 서블릿파일은 값을 어떻게 주고 받을까 ?

 

Ajax에서 JSON 타입으로 데이터를 받겠다고 명시하는 것은, 서버에서 객체 자체를 보내기 위한 방법이다. 일반적으로 Ajax를 사용하여 서버와 통신할 때, 단순한 텍스트나 숫자 등의 원시 데이터 뿐만 아니라, 복잡한 구조를 가진 객체를 주고받아야 하는 경우가 많다. 이때 JSON은 자바스크립트 객체의 표현 방식이며, 복잡한 데이터를 구조화하고 표현하기에 적합하다.

< 서블릿이나 서버에서 객체 자체를 보낼 때는 이를 JSON 형식으로 변환하여 응답으로 보내는 것이 일반적이다.

이렇게 하면 클라이언트 측에서는 JSON으로 파싱하여 자바스크립트 객체로 사용할 수 있다.

JSON은 객체, 배열, 문자열, 숫자, 불리언 등을 포함하는 다양한 데이터 형식을 지원하므로,

다양한 데이터를 효율적으로 주고받을 수 있다. >

따라서, Ajax로 서버와 통신하여 객체 자체를 주고받을 때에는 JSON 타입으로 데이터를 주고받는 것이 일반적이고 효율적인 방법이다. JSON은 클라이언트와 서버 간의 데이터 교환에 있어서 널리 사용되는 형식 중 하나이며, 대부분의 현대적인 웹 애플리케이션에서 주요한 데이터 교환 형식으로 사용된다.

 

요약하면, 서블릿에서 ArrayList를 JSON 형식으로 변환하여 보내고, Ajax가 해당 JSON 데이터를 받고 파싱한 뒤 객체로 사용하는 것이 가장 일반적인 방법이다. 이렇게 하면 객체의 속성에 접근하여 데이터를 활용할 수 있다.

 

Ajax는 기본적으로 서버로부터 받은 데이터를 문자열로 처리합니다. 따라서 서블릿이 텍스트를 응답으로 보낸다면, Ajax는 그냥 해당 문자열을 받는 것입니다.

 

  • 서블릿에서 다음과 같이 텍스트를 응답으로 보내는 경우:

 

```java 객체 에서는

PrintWriter out = response.getWriter();

out.print("Hello, Ajax!");

```

 

  • 클라이언트에서는 아래와 같이 Ajax 요청을 보낼 수 있습니다:

 

```javascript 에서는

$.ajax({

url: "your_server_url",

method: "GET", // 또는 POST, PUT 등 HTTP 메서드 지정

success: function(data) {

// 성공적으로 데이터를 받았을 때 처리할 코드

console.log(data); // 출력: "Hello, Ajax!"

},

error: function(error) {

// 요청이 실패하거나 에러가 발생했을 때 처리할 코드

console.error("Error:", error);

}

});

```

 

위의 예시에서 `dataType`을 명시하지 않았지만, Ajax는 서버로부터 받은 "Hello, Ajax!"를 그냥 문자열로 처리하여 `data` 변수에 할당한다.

 

물론 데이터의 복잡성에 따라 명시적으로 데이터 타입을 설정하는 것이 좋을 수도 있다. 그러나 단순한 텍스트를 주고받는 경우에는 별도의 데이터 타입 설정 없이도 잘 작동한다.

 

✔️ 에러 해결방안

 

ajax 메서드는 자료에 대한 요청을 맵핑 하여 비동기 전용 서블릿 파일과 연결될 수 있도록 수행하는데

이때 ajax의 데이터 타입은 보통 json 타입입니다. 따라서 비동기 전용 서블릿 파일은 자바 객체 인데 값을 전달 받으면 객체로 받지 못하고 텍스트 to string으로 받게 됩니다. 객체의 값을 받아오기 위해서는 json jar 파일을 다운받아 서블릿 파일 내에서 json 타입으로 변환해서 값을 보내주면 됩니다.

 

구글에서 제공한 gson.jar 를 다운받았다 !

비동기 전용 서블릿 파일에서 json 타입으로 변환 해준다.

package controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

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

import com.google.gson.Gson;

import model.ProductDAO;
import model.ProductVO;

@WebServlet("/fruitkha-1.0.0/filterSearch.do")
public class Test2 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public Test2() {
        super();
    }

    private void doAction(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    		response.setCharacterEncoding("UTF-8");
          ArrayList<ProductVO> pdatas = new ArrayList<ProductVO>();
          
          ProductVO pVO = new ProductVO();
          ProductDAO pDAO = new ProductDAO();
          
          //   사용자가 입력한 이름 키워드 값 가져오기.
          String pName = request.getParameter("pName");
          
          System.out.println("log : FilterSearch.java : doAction : pName : " + pName);
          
          //   사용자가 입력한 이름 키워드 값을 pVO 객체에 set.
          pVO.setpName(pName);
          
          //   이름 키워드 값을 가지고, DB 거치고 나오기.
          pdatas = pDAO.selectAll(pVO);
          
          System.out.println("log : FilterSearch.java : doAction : pdatas : " + pdatas);
          
          //   out 객체에 담아서 View 에게 보내기.
          PrintWriter out = response.getWriter();
          
          //   View 에게 pdatas 데이터 보내기.
          //out.print(pdatas);
          Gson gson = new Gson();

          // pdatas를 JSON 형식으로 변환
          String json = gson.toJson(pdatas);

          // JSON 형식의 문자열로 응답
          response.setContentType("application/json");
          out = response.getWriter();
          out.print(json);
       }
       
      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doAction(request, response);
      }

      protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doAction(request, response);
      }

}
 

 

결과

 

 

 

728x90
반응형