Я генерирую qr-код для оплаты.
public GenerateQrResponse createQr(CreateQrRequest request) {
var bnplEntity = bnplRepository.findByOrderId(request.getOrderNumber());
if (bnplEntity.isEmpty()) {
messengerUtils.sendTelegramBotMessage(telegramChatId, "bnpl not found by orderId. createQr method, orderNumber = " + request.getOrderNumber());
throw new RuntimeException("bnpl entity not found while requesting qr code for bnpl with order number = " + request.getOrderNumber());
}
var bnplDto = bnplService.prepareBnplResponse(bnplEntity.get());
bnplDto.setBnplId(bnplEntity.get().getId());
bnplDto.setDate(bnplEntity.get().getCreatedAt());
String linkUrl = bnplUrlService.getBnplUrl(bnplDto);
BufferedImage logoImage = createRedCircleImage(50, 50);
String logoBase64 = convertImageToBase64(logoImage);
try {
QRCodeWriter qrCodeWriter = new QRCodeWriter();
BitMatrix bitMatrix = qrCodeWriter.encode(linkUrl, BarcodeFormat.QR_CODE, 250, 250, getQrCodeHintMap());
BufferedImage qrImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
byte[] logoBytes = Base64.getDecoder().decode(logoBase64);
ByteArrayInputStream logoStream = new ByteArrayInputStream(logoBytes);
logoImage = ImageIO.read(logoStream);
BufferedImage combined = new BufferedImage(250, 250, BufferedImage.TYPE_INT_RGB);
Graphics2D g = combined.createGraphics();
g.drawImage(qrImage, 0, 0, null);
int x = (combined.getWidth() - logoImage.getWidth()) / 2;
int y = (combined.getHeight() - logoImage.getHeight()) / 2;
g.drawImage(logoImage, x, y, null);
g.dispose();
ByteArrayOutputStream combinedOutputStream = new ByteArrayOutputStream();
ImageIO.write(combined, "PNG", combinedOutputStream);
byte[] imageBytes = combinedOutputStream.toByteArray();
return new GenerateQrResponse(Base64.getEncoder().encodeToString(imageBytes), request.getOrderNumber(), request.getAmount(), linkUrl);
} catch (IOException | WriterException e) {
throw new RuntimeException(e.getMessage());
}
}
Проблема в том, что когда я создаю DTO для qr, мне нужно указать адрес. Если адрес будет на английском языке, проблем не будет. Но если адрес будет написан кириллицей, то в qr-ссылке весь кириллический текст станет типа ?????
Основная проблема в том, что у меня все адреса написаны кириллицей, наша система работает так. Здесь ДТО
return BnplDTO.builder()
.bnplId(bnpl.getId())
.amount(bnpl.getAmount())
.bin("111111111111")
.address("ул. Астана 58А")
.legalName("Example")
.build();
Я использую библиотеку qrgen
<dependency>
<groupId>net.glxn</groupId>
<artifactId>qrgen</artifactId>
<version>1.4</version>
</dependency>
Есть идея сменить библиотеку, но может кто-нибудь знает, как решить эту проблему? заранее спасибо
@TimRoberts, спасибо, помог поставить эту строку кодаhints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); и теперь qr выполняет ссылку noraml с кириллицей!




QR-коды AFAIK используются для указания URL-адресов. И они обычно кодируются как UTF-8. Чтобы быть уверенным, используйте URL-кодирование. См. https://stackoverflow.com/a/10786112/4222206
Другой вариант — не помещать все данные в QR-код, а создать URL-адрес с кодом (транзакции), который ведет обратно на ваш веб-сайт, который затем предоставляет полную информацию.
Проблема в том, что все, что закодировано в QR-матрице, представляет собой строку байтов. Нет ничего, что указывало бы на набор символов. Читатель не может сказать, что это должно быть.