에지 확장 프로그램은 에지브라우저에 프로그램을 추가하여 브라우저 기능을 확장하는 프로그램입니다.

chatGPT는 많이들 알고 계시는 대화형 인공지능 프로그램입니다.

 

이 글들의 목표는 에지브라우저 확장을 통해 작은 창을 띄우고 확장창에 고정 주제를 적어두고 이 메시지를 대화창에 전송하는것입니다.

 

만들어보게 된 이유는 chatGPT를 사용하던 중 고정 주제에 대해서 이야기 하는 경우 맥락이 안맞는 대답을 하는것 같아서 주제 고정을 위해서 간단한 확장프로그램을 만들어 보기로 했습니다.

보통 크롬확장이 많이 있지만 현재 사용환경이 에지여서 에지 확장프로그램을 만들어 보기로했습니다. 크롬 확장과도 큰차이가 없는 것으로 알고 있습니다.

 

Create an extension tutorial, part 1 - Microsoft Edge Development | Microsoft Learn 에 있는 확장 설정 까지 진행해보겠습니다.

설명하는 코드는 tistory_openapi/edgeGpt1 at master · a3040/tistory_openapi (github.com)  참조하시면 됩니다.

manifest.json, popup.html 두개의 파일과 에지 브라우저에 추가하는 부분까지 설명해보도록하겠습니다.

 

개발 환경은 vistual studio code, 에지브라우저이고, 언어는 javascript, html입니다.


에지확장프로그램의 구성
- Manifest 파일:
에지 확장 프로그램의 설정과 정보를 담는 JSON 형식의 파일입니다.
프로그램 이름, 버전, 아이콘, 권한 등의 정보를 정의합니다.

- Background Script (백그라운드 스크립트):
에지 확장 프로그램의 백그라운드에서 실행되는 JavaScript 코드입니다.
백그라운드에서 실행되는 주기적인 작업, 이벤트 처리 등을 담당합니다.

- Content Script (콘텐트 스크립트):
웹 페이지의 콘텐츠와 상호작용하기 위해 삽입되는 JavaScript 코드입니다.
웹 페이지의 DOM 요소에 접근하고 조작할 수 있습니다.

- Popup (팝업):
사용자 인터페이스를 제공하는 팝업 창입니다.
사용자의 입력을 받고 처리하는 등의 작업을 수행합니다.

 

이 설정 중 팝업 창Manifest 을 예제에서 사용했습니다.

manifest.json 

{
    "name": "Hello",
    "version": "0.0.1",
    "manifest_version": 3,
    "description": "Hello",
    "action": {
        "default_popup": "popup.html"
    }
}

설정파일중 version :3, action은 popup.html 파일을 신경 써주시면 됩니다. 설정파일에 의해 확장프로그램 버튼이 클릭되면 popup.html파일이 사용자와 대화하기 위해 나타납니다. 위쪽 맨처음 이미지 참고

 

popup.html 

<html>
    hello
    <br /><br /><br /><br /><br /><br />    
</html>

만들어진 두개의 파일을 에지브라우저의 확장프로그램으로 등록하는 방법입니다.

 

에지 &gt; 확장관리
확장프로그램 &gt; 개발자모드 설정

확장관리 > 개발자모드를 설정하시고 > 압축 풀린 파일 로드 > 방금만든 확장프로그램 폴더 선택 을 합니다.

정상적으로 로드 되면 확장관리 에 만든 확장 프로그램이 나타나게 됩니다

에지브라우저에 방금 만든 확장프로그램 아이콘이 보이지 않는 경우 .확장에서 1번 눈모양을 클릭해줍니다. 그렇게 하면 맨 처음 이미지처럼 만든 확장프로그램 아이콘이 보이게 됩니다. 이후 우리가 만든 확장아이콘을 클릭하면 작성했던 popup.html이 실행되며 hello라고 출력된 작은 인터페이스 화면이 브라우저에 나타나게 됩니다.

작업 상태

- Jpa 를 이용하고 있었고, todo라는 클래스 체운후 insert 후 결과 값을 json응답으로 응답해주는 메소드 작업중이었습니다.

- 상황은 work:todo=1:N 관계에 있었습니다.

- 에러가 발생하면서 무언가 무한루프가 도는 듯한 느낌도 있었습니다.
 
에러 메시지 

- java.lang.IllegalStateException: getOutputStream() has already been called for this response at org.apache.catalina.connector.Response.getWriter(Response.java:561)  at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:226)

- 에러 메시지를 기반으로 상위 filter등을 살폈으나 특이사항은 없었습니다.

java.lang.IllegalStateException: getOutputStream()

원인

        at co m.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:733) 
        at co m.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774) 
        at co m.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) 
        at co m.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:733) 
        at co m.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)

로그를 살피던 중 이 부분이 무한 루프가 도는 느낌이어서 검색해 보니.. json으로 변환시 Enitty참조문제로 무한 루프가 발생할수 있다고 해서 두개의 Entity Todi, Working을 살펴봤습니다.

 

@Entity
public class Todo {
...
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "working_id")
    private Working working;
}

@Entity
public class Working {
...

    @OneToMany(mappedBy = "working", cascade = CascadeType.ALL)
    @OrderBy("id DESC")
    private List<Todo> todos; 
}

검색 결과에서 발견한것 처럼 상호 참조가 있었습니다.

 


처리

@Entity
public class Working {
...

    @OneToMany(mappedBy = "working", cascade = CascadeType.ALL)
    @OrderBy("id DESC")
    @JsonIgnore  // 어노테이션을 사용하여 직렬화에서 제외시킴
    private List<Todo> todos; 
}

 

작업 상태

- tailwind로 css파일 생성중이었습니다. tailwind.config.js파일 생성후 

tailwindcss -i ./input.css -o ./man/man.css --watch 실행중에 나타났습니다.
 
에러 메시지 


원인

- “Unterminated string constant” 오류는 문자열의 닫는 따옴표를 빼먹거나, 문자열 내에서 이스케이프 문자를 제대로 처리하지 않거나, 문자열이 여러 줄로 나누어져 있을 때 발생합니다.  라고 bing 친구가 답해줬는습니다.

- 덕분에 expression.js파일을 살펴봤으나 원인은 찾지 못했습니다.

- 당연하게도 배포된 코드에서 문제를 찾기 보다는 만든 파일을 찾았어야했습니다.

- tailwind.config.js 부분입니다. tailwind에서 css 스캔할 대상 설정 부분인데 따옴표 가 빠져 있었습니다.

- 에러는 node_modues쪽에서 나왔네요.

 

처리

- 따옴표 추가 후 정상 동작합니다.

- 배포 코드를 의심하기 보단 나 자신을 먼저 의심합시다.OTL

 

작업 상태

- 페이징 작업 중에 발생핬습니다. ?page=1 형태의 요청이 와야할는데 null 인 경우가 있었습니다.
 
에러 메시지 

 WARN  o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required request parameter 'page' for method parameter type Integer is not present]

원인

- 기본값 처리가 미흡했습니다.

 

public Page<Note> viewAllGetMethod(Model model
,@PathVariable("categoryId") Long categoryId
,@RequestParam(value = "page") Integer page
) { 

처리

public Page<Note> viewAllGetMethod(Model model
,@PathVariable("categoryId") Long categoryId
,@RequestParam(defaultValue = "1", value = "page") Integer page
) { 

참고

- 이번 에러는 기본값 미흡도 있지만, client측 코드 요청 부분의 페이징 기능 업데이트 후 서버 재시작을 안한 상황에서 page값이 없이 들어와서 발생했습니다. 서버 코드 수정없이 client 재시작으로 해결됐으나, 대응 차원에서 서버도 수정했습니다.

+ Recent posts