크롬이나 요즘 브라우져에 f12를 누르고 텝에 네트워크를 클릭하면

 이런식으로 http 통신 내용들을 볼수 잇습니다.
 
서블릿의 역할은 저 녹색부분을 제외하고 전부 자동화 해줍니다.
즉 스프링에서는 비지니스 로직에 집중하여 생산성이 높게 진화가 된겁니다.

개발자들의 어려운걸 해결해주기 위해서 탄생한 서블릿
 
이미지 출처 링크:
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., -

www.inflearn.com

 
기본적인 웹 실행 구조

이미지 출처 링크:
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., -

www.inflearn.com

예시)

이미지 출처 링크:
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., -

www.inflearn.com

서블릿 컨테이너는 객체 생성,호출, 초기화,종료해주는 생명주기 관리 
싱글톤으로 관리
싱글톤으로 하는 이유
 
1.고객의 요청이 올떄 마다 계속 객체 생성은 비효율적
2.최초 로딩시점에 서블릿 객체를 미리 만들어두고 재활용
3.모든 고객 요청은 동일한 서블릿 객체 인스턴스에 접근 
4.공유 변수 사용주의
5. 서블릿 컨테이너 종료시 함께 종료
 
작년에 공부했던건데 기억에 사라진게 있네요 
복습 중요하네요 ㅠ 
 
 
 

' > Spring' 카테고리의 다른 글

서버사이드 렌더링, 클라이언트 렌더링  (0) 2023.06.19
쓰레드  (0) 2023.06.19
web server , was(web application server) 차이  (0) 2023.06.19
웹 로드맵  (0) 2022.09.13
WebSecurityConfigurerAdapter 사용 불가  (0) 2022.09.01

web server

http 기반으로 동작

정적 리소스 제공, 기타 부가기능

정적 html, css, js,이미지,영상

예) nginx, apache

 

was(web application server)

http 기반 으로 동작

웹서버 기능 포함+ (정적 리소스 제공가능)

프로그램 코드를 실행해서 애플리케이션 로직 수행

동적 html, http api(json)

서블릿, 스프링mvc

예) tomcat,jetty,undertow

 

후기

알고 있는 내용이었지만 다시한번 정리하는 좋은 기회가 되었습니다.

 

' > Spring' 카테고리의 다른 글

쓰레드  (0) 2023.06.19
서블릿  (0) 2023.06.19
웹 로드맵  (0) 2022.09.13
WebSecurityConfigurerAdapter 사용 불가  (0) 2022.09.01
junit5 >> MockitoAnnotations.initMocks 사용법  (0) 2022.08.17

이번에 jpa쪽 조인에 대해서  알게 되었는데요.
생각보다 조금 어려웠습니다. 아직 db 설계에 대해서는 많이 미숙한듯 합니다.
진짜 db를 여러번 고쳤습니다.
 
내일은 프론트단을 완성시켜 장바구니리스트를 보이도록 할겁니다.
 

p.s
현재 회사에서는 procedure를 사용해서 직접쿼리문으로 join을 했습니다. 
회사의 테이블이 엄청나게 많고 너무 복잡하다보니 db쪽에 종속되는 방향으로 개발들이 되어 있습니다. (sql mapper 방식)
제 개인프로젝트는 orm 방식으로 했고요.  상당히 많은 it 회사들이 orm 방식으로 개발해서 일단 이쪽으로 공부를 하고 있습니다.
아직 모르는게 많고 배울게 엄청나게 많다고 느끼고 있습니다.
 
장바구니 리스트를 뽑아줄 jpa

//장바구니 리스트
    public List<BasketsWithProduct> findAll(String userName,String status, int page, int size) {
        List<BasketsWithProduct> basketsList = null;
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        try{
            CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
            CriteriaQuery<BasketsWithProduct> criteriaQuery = criteriaBuilder.createQuery(BasketsWithProduct.class);

            Root<Baskets> root = criteriaQuery.from(Baskets.class);

            Join<Baskets, Product> fileJoin = root.join("product", JoinType.INNER);

            // 복합키 검색 조건 생성
            Predicate compositeKeyPredicate = criteriaBuilder.equal(root.get("basketId").get("usersId"),userName );

            // 상태 검색 조건 생성
            Predicate statusPredicate = criteriaBuilder.equal(root.get("status"), status);

            // 검색 조건 결합
            Predicate finalPredicate = criteriaBuilder.and(compositeKeyPredicate, statusPredicate);

            //검색
            criteriaQuery.select(criteriaBuilder.construct( BasketsWithProduct.class, root, fileJoin ));
            criteriaQuery.where(finalPredicate);

            TypedQuery<BasketsWithProduct> typedQuery = entityManager.createQuery(criteriaQuery);
            typedQuery.setFirstResult((page - 1) * size);
            typedQuery.setMaxResults(size);

            // 페이지 조건
            basketsList = typedQuery.getResultList();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(entityManager!=null){
                entityManager.close();
            }
        }
        return basketsList;
    }

BasketsWithProduct 객체

@Getter
@Setter
public class BasketsWithProduct {
   private Baskets baskets;
   private Product product;
   public BasketsWithProduct(Baskets baskets, Product product) {
      this.baskets = baskets;
      this.product = product;
   }
}

Basket 테이블 

@Entity
@Table(name = "Baskets")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Baskets {

    @EmbeddedId
    private BasketId basketId;

    //status 장바구니 B, 삭제 D, 결재 C
    @NotEmpty
    @Column(name = "STATUS")
    private String status;

    //produtnumber + userid
    @NotNull
    @Column(name = "BIND_NUMBER")
    private String bindNumber;

    @ManyToOne
    @JoinColumn(name = "product_id", referencedColumnName = "ID")
    private Product product;

}

Product 테이블 

@Entity
@Getter
@Table(name = "PRODUCT")
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "PRODUCT_SEQ")
    @SequenceGenerator(name = "PRODUCT_SEQ", sequenceName = "PRODUCT_SEQ", allocationSize = 1)
    @Column(name = "ID")
    private Long id; //key
    
    @NotEmpty
    @Setter
    @Column(name = "PRODUCT_NAME")
    private String productName;

    @NotNull
    @Setter
    private BigDecimal price;

    @NotEmpty
    @Setter
    @Column(name = "IMAGE_URL")
    private String imageUrl;

    @NotEmpty
    @Setter
    @Column(name = "VIDEO_URL")
    private String videoUrl;

    @NotNull
    @Setter
    @Column(name = "DESCRIPTION")
    private String description;
}

 

일단 입력 하고 테이블을 불러오는데는 성공했습니다.

일단 baskets 테이블에서는 조회를 전부 하고있고요

이런식으로 product_id 기준으로 조인해서 데이터의 이름과 가격, 이미지 불러올겁니다 .

코드:

    //장바구니 리스트
    public List<Baskets> findAll(String userName,String status, int page, int size) {
        List<Baskets> basketsList = null;
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        try{
            CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
            CriteriaQuery<Baskets> criteriaQuery = criteriaBuilder.createQuery(Baskets.class);

            Root<Baskets> root = criteriaQuery.from(Baskets.class);
            //조인
            // Join<Baskets, Product> jointable = root.join("product", JoinType.INNER);
            // 복합키 검색 조건 생성
            Predicate compositeKeyPredicate = criteriaBuilder.equal(root.get("basketId").get("usersId"),userName );

            // 상태 검색 조건 생성
            Predicate statusPredicate = criteriaBuilder.equal(root.get("status"), status);

            // 검색 조건 결합
            Predicate finalPredicate = criteriaBuilder.and(compositeKeyPredicate, statusPredicate);
            
            //데이터 조회
            criteriaQuery.select(root);
            criteriaQuery.where(finalPredicate);
             
            //페이지 사이즈
            TypedQuery<Baskets> typedQuery = entityManager.createQuery(criteriaQuery);
            typedQuery.setFirstResult((page - 1) * size);
            typedQuery.setMaxResults(size);
            
            basketsList = typedQuery.getResultList();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(entityManager!=null){
                entityManager.close();
            }
        }
        return basketsList;
    }

 

 

 

 

 

금일 약속이 있어서 진행을 조금밖에 못햇네요.

baskets 테이블이랑 users 테이블정도 변경만 했습니다. 

내일은 장바구니 마무리하도록 하겠습니다.

완성했습니다.

일단 api key는 https://platform.openai.com/account/api-keys

 

OpenAI API

An API for accessing new AI models developed by OpenAI

platform.openai.com

받으시면 되고요 .

영상 :

코드 :

@RestController
public class ChatGptController {
    @Autowired
    private ChatGptService chatGptService;

    @PostMapping("/api/ChatGptApi")
    public ResponseEntity<String> ChatGptsPost(@RequestBody ChatGpt chatGpt, HttpServletRequest request) {
        String CHATGPT_API_KEY  = "";
        HttpSession session = request.getSession(false);
        String answer="연결을 실패하였습니다.";
        if (session == null || session.getAttribute("user") == null) {
           //  세션에 사용자 정보가 없으면 로그인 페이지로 리다이렉트
            return  ResponseEntity.ok(answer);
        }

        try{
             CHATGPT_API_KEY=chatGpt.getApikey();
             answer=chatGptService.getChatResponse(chatGpt.getInput(),CHATGPT_API_KEY);
        }catch (Exception e){
            System.out.println("error");
            return  ResponseEntity.ok(answer);
        }
        return  ResponseEntity.ok(answer);
    }
}

@Service
public class ChatGptService {
    private  RestTemplate restTemplate;
    private final String chatGptApiUrl = "https://api.openai.com/v1/chat/completions";

    public ChatGptService() {
        this.restTemplate = new RestTemplate();
    }

    public String getChatResponse(String userInput,String apiKey ) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setBearerAuth(apiKey);

        String requestBody = "{\"model\":\"gpt-3.5-turbo\",\"messages\":[{\"role\":\"system\",\"content\":\"" + userInput + "\"}]}";
        HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, headers);

        // ChatGPT API 호출
        ResponseEntity<String> responseEntity=null;
        try{
           responseEntity = restTemplate.exchange(chatGptApiUrl, HttpMethod.POST, requestEntity, String.class);
        }catch (Exception e){
            e.printStackTrace();
        }

        // ChatGPT API 응답 처리
        String chatResponse = responseEntity.getBody();

        return chatResponse;
    }
}

요즘 핫한 ai chat를 이용해서 chat gpt 3.5 api 입니다.
갑자기 하고 싶어서 만들었습니다. 
백엔드는 완성했고 내일 프론트엔드쪽도 완성할 예정입니다.
spring에서 데이터를 받아서 vue에서 랜더링 해주는건데요.
코드는 아래와 같습니다.
 
P.S 
Chat gpt API-KEY를 구하는것은 다른 블로그에서 참고 하시면됩니다. 
그리고 이건 3.5 버전이고 4.0 버전으로 변경하고싶시면 공식문서 참고해주세요 가격도 달라요
 
service

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.HttpHeaders;
@Service
public class ChatGptService {
    private  RestTemplate restTemplate;
    private final String chatGptApiUrl = "https://api.openai.com/v1/chat/completions";

    public ChatGptService() {
        this.restTemplate = new RestTemplate();
    }

    public String getChatResponse(String userInput,String apiKey ) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setBearerAuth(apiKey);

        String requestBody = "{\"model\":\"gpt-3.5-turbo\",\"messages\":[{\"role\":\"system\",\"content\":\"" + userInput + "\"}]}";
        HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, headers);

        // ChatGPT API 호출
        ResponseEntity<String> responseEntity=null;
        try{
           responseEntity = restTemplate.exchange(chatGptApiUrl, HttpMethod.POST, requestEntity, String.class);
        }catch (Exception e){
            e.printStackTrace();
        }

        // ChatGPT API 응답 처리
        String chatResponse = responseEntity.getBody();

        return chatResponse;
    }
}

controller

import kr.co.kshproject.webDemo.Applicaiton.ChatGptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@RestController
public class ChatGptController {
    private static final String CHATGPT_API_KEY = "APIKEY"
    
    @Autowired
    private ChatGptService chatGptService;

    @PostMapping("/api/ChatGptApi")
    public ResponseEntity<String> ChatGptsPost(@RequestBody String input, HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        String answer="연결을 실패하였습니다.";
        if (session == null || session.getAttribute("user") == null) {
           //  세션에 사용자 정보가 없으면 로그인 페이지로 리다이렉트
            return  ResponseEntity.ok(answer);
        }
        
        try{
             answer=chatGptService.getChatResponse(input,CHATGPT_API_KEY);
        }catch (Exception e){
            return  ResponseEntity.ok(answer);
        }
        return  ResponseEntity.ok(answer);
    }
}

 

장바구니쪽을 조금 생각을 해봤는데요. db쪽을 좀더 바꿀것 같습니다.
기존에는 
주문상품들이 있는지 확인해서 카운팅만 업데이트 해주려고 했는데요.
곰곰히 생각해보니 데이터를 insert를 쭉 시키고 
어차피 update에서 상태만 바꿔줄거여서 db를 다시한번 변경해야할듯합니다. 
현재 코드 상태 :(변경 예정) 

 @PostMapping("/Basket/Post")
    public ResponseEntity<?> PostBaskets(@RequestBody Baskets baskets, HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session == null || session.getAttribute("user") == null) {
            // 세션에 사용자 정보가 없으면 로그인 페이지로 리다이렉트
            return ResponseEntity.badRequest().build();
        }
        //유저
        String userId="";
        Object attribute = session.getAttribute("user");
        if (attribute instanceof org.springframework.security.core.userdetails.User) {
            org.springframework.security.core.userdetails.User user = (org.springframework.security.core.userdetails.User) attribute;
           // notice.setUsername(user.getUsername());
              userId=user.getUsername();
        }
        baskets.getBasketId().setUsersId(userId);

        //날짜
        LocalDateTime currentDateTime = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String formattedDateTime = currentDateTime.format(formatter);
        baskets.getBasketId().setDate(formattedDateTime);

        //TODO
        //날짜 갯수카운팅 후 데이터 변경 상품, 유저아이디 체크할것
        baskets.setCount(1L);
        try{
            basketService.save(baskets);
        }catch (Exception e){
            return ResponseEntity.badRequest().build();
        }
        return ResponseEntity.ok().build();
    }

 

+ Recent posts