반응형
250x250
Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

샘오리_개발노트

[JAVA] Zxing 라이브러리로 QR을 만들어보자 본문

카테고리 없음

[JAVA] Zxing 라이브러리로 QR을 만들어보자

샘오리 2024. 4. 22. 14:50
728x90
반응형

언어:  Java 17

라이브러리: Zxing

 

공통

 

1. 사용하는 빌드 관리도구에 맞게 라이브러리 추가

https://mvnrepository.com/artifact/com.google.zxing/core

https://mvnrepository.com/artifact/com.google.zxing/javase

 

2. QR을 앞단에서 출력하기 위해서는 바이트로 받아야 이미지로 출력할 수 있기 때문에

컨트롤러단에서 Return Type을 아래와 같이 설정해야한다.

ResponseEntity<byte[]>

 


 

시나리오 1: 앞단에서 이미 QR 이미지로 인코딩 할 데이터가 있는 경우 (예: url)

 

 

시나리오 1-1: 테스트를 위해 QR 이미지로 출력 가능한 데이터는

이미 자바단에서 하드코딩이 되어있고

String url = "https://samori.tistory.com/";

앞단에서는 앵커 태그만 존재하는 경우겠다.

 

 

HTML

<div>
    <h3>샘오리 블로그 가기</h3>
    <a href="/qr/samOriBlog">샘오리 블로그 가기</a>
</div>

 

이해를 돕기 위해 css를 입힌 모습

 

Controller

    @GetMapping("/qr/samOriBlog")
    public ResponseEntity<byte[]> qrSamOri() throws WriterException {

        int width = 300;
        int height = 300;
        String url = "https://samori.tistory.com/";

        BitMatrix encode = new MultiFormatWriter()
                .encode(url, BarcodeFormat.QR_CODE, width, height);
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(encode, "PNG", out);
            return ResponseEntity.ok()
                    .contentType(MediaType.IMAGE_PNG)
                    .body(out.toByteArray());

        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

 

앵커 태그를 클릭 하면 같은 qr코드가 출력 될 것이다.

 

 

 


 

시나리오 1-2: 테스트라 해도 하드코딩은 오바지..

앞단에서 사용자가 입력한 값으로 qr를 출력하고 싶은 경우 

 

<div>
    <h3>가고 싶은 블로그</h3>
    <form type="POST" action="/qr/blogToVisit">
        <input type="text" name="blogUrl">
        <button type="submit">출력</button>
    </form>
</div>

 

 

    @GetMapping("/qr/blogToVisit")
    public ResponseEntity<byte[]> blogToVisit(@RequestParam(value = "blogUrl") String blogUrl) throws WriterException {

        int width = 300;
        int height = 300;
        BitMatrix encode = new MultiFormatWriter()
                .encode(blogUrl, BarcodeFormat.QR_CODE, width, height);
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(encode, "PNG", out);
            return ResponseEntity.ok()
                    .contentType(MediaType.IMAGE_PNG)
                    .body(out.toByteArray());

        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

 

 

 

 


시나리오 2: 사용자가 입력한 값을 받아서 DB에 조회하고 일치하는 행의 QR 데이터를 읽어와서 이미지로 출력하기

 

예를 들어 MEMBER 테이블이 있다고 가정해보자.

 

PK 값은 사번이고

각 사번에 맞게 QR 코드 칼럼에 hexadecimal 코드 데이터가 qrCode라는 칼럼에 존재한다. 

 

1. 사용자는 사번을 입력하고 컨트롤러에 전달한다.

2. 컨트롤러는 전달받은 사번을 db에 비교 조회하여 그 사번에 맞는 행을 가져온다.

3. 가져온 행의 qrCode 칼럼만 추려서 이를 변수화 한다.

4. 변수화 한 데이터를 인코딩하고 인코딩 한 바이트를 앞단에 return하는 원리이다.

 

앞단에서 파라미터로 전달할 것인지 혹은 url에 담아서 보내든지에 따라 아래처럼 나뉜다.

@RequestParam(value = "전달할 값") String 전달할 값
@PathVariable(value = "전달할 값") String 전달할 값

 

아래 샘플의 경우 간단한 에러 핸들링 로직이 추가된 소스이다.

    public ResponseEntity<byte[]> 함수명(String 파라미터) {
        DTO명 hexCode = 인터페이스명.findByPK칼럼(파라미터);
        // 가져온 행의 qr칼럼만 가져와서 String 변수에 넣어주기
        String hexCodeColumn = hexCode.getQrCode();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            generateQRCode(outputStream, hexCodeColumn);
        } catch (WriterException | IOException e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }

        byte[] qrImage = outputStream.toByteArray();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_PNG);
        headers.setContentLength(qrImage.length);

        return new ResponseEntity<>(qrImage, headers, HttpStatus.OK);
    }

    private void generateQRCode(ByteArrayOutputStream outputStream, String content) throws WriterException, IOException {
        int width = 너비값;
        int height = 높이값;

        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");

        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);

        MatrixToImageWriter.writeToStream(bitMatrix, "PNG", outputStream);
    }

 

728x90
반응형
Comments