java - 将 Base64 编码的字节 [] 作为 JSON MIME 类型传递
问题描述
我有一个 REST 服务@Produces(MediaType.APPLICATION_JSON)
。在 REST 服务中,我创建了一个 Image 类型BufferedImage
,然后将其ImageIO
作为 png 图像写入。接下来,我将此图像编码为Base64 encoded
字符串。现在我需要以JSON
格式返回这个编码字符串,然后在客户端我需要在img
标签中使用 Base64 字符串,如下所示:
<img id="captchaImage" src="data:image/png;base64,<%=Base64ImageString%>"/>
我如何将 Base64 作为MediaType.APPLICATION_JSON
代码 :
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Base64;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
@RestService
@Named("CaptchaServlet")
@Path("/reCaptchaImg")
@Produces(MediaType.APPLICATION_JSON)
public class CaptchaServlet implements ICaptchaServlet{
@Override
public Response processRequest(HttpServletRequest request) throws GeneralSecurityException, IOException {
try {
System.out.println("shaan Inside processRequest");
int width = 150;
int height = 50;
//Random string generation happens
Random r = new Random();
int length = 6;
System.out.println("shaan Creating string parameter");
StringBuffer captchaStringBuffer = new StringBuffer();
for (int i = 0; i < length; i++) {
int baseCharNumber = ((r.nextInt((500-1)+1)+1) % 62);
int charNumber = 0;
if (baseCharNumber < 26) {
charNumber = 65 + baseCharNumber;
}
else if (baseCharNumber < 52){
charNumber = 97 + (baseCharNumber - 26);
}
else {
charNumber = 48 + (baseCharNumber - 52);
}
captchaStringBuffer.append((char)charNumber);
}
String captchaString = captchaStringBuffer.toString();
System.out.println("The random string generated is : "+captchaString);
char[] s3 = captchaString.toCharArray();
System.out.println("shaan1");
//Converting Captcha String to Image
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bufferedImage.createGraphics();
System.out.println("shaan2");
Font font = new Font("Georgia", Font.BOLD, 18);
g2d.setFont(font);
System.out.println("shaan3");
RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
System.out.println("shaan4");
rh.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHints(rh);
System.out.println("shaan5");
GradientPaint gp = new GradientPaint(0, 0, Color.red, 0, height / 2, Color.black, true);
g2d.setPaint(gp);
g2d.fillRect(0, 0, width, height);
g2d.setColor(new Color(255, 153, 0));
System.out.println("shaan6");
String captcha = String.copyValueOf(s3);
System.out.println("shaan7");
int x = 0;
int y = 0;
for (int i = 0; i < s3.length; i++) {
x += 10 + (Math.abs(r.nextInt()) % 15);
y = 20 + Math.abs(r.nextInt()) % 20;
g2d.drawChars(s3, i, 1, x, y);
}
g2d.dispose();
System.out.println("shaan8");
System.out.println("shaan9");
//Sending Image in output
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", baos);
byte[] imageData = baos.toByteArray();
System.out.println("shaan10" + captcha);
request.getSession().setAttribute("captcha", captcha);
System.out.println("shaan11");
baos.flush();
baos.close();
System.out.println("shaan12");
System.out.println("The imageData is :"+imageData);
//Encoding to Base64
byte[] encoded = Base64.getEncoder().encode(imageData);
System.out.println("The encoded is :"+encoded);
return Response.ok(encoded, MediaType.APPLICATION_JSON).build();
}catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("In Error Catch block");
e.printStackTrace();
return Response.status(Status.BAD_REQUEST).build();
}
}
仅供参考,代码中行的输出是:
System.out.println("The imageData is :"+imageData);
The imageData is :[B@238bbb96
System.out.println("The encoded is :"+encoded);
The encoded is :[B@1a477e17
解决方案
我认为您尝试做的事情行不通,对我来说也没有意义。
数据 URI 旨在将图像的数据直接包含在 HTML 中,而不是从外部 URL 链接。
您应该只返回图像而不将其编码为 Base64 并直接链接它。
您可以将代码更改为:
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
@Named("CaptchaServlet")
@Path("/reCaptchaImg")
@Produces("image/png")
public class CaptchaServlet {
@GET
public Response processRequest(@Context HttpServletRequest request) {
try {
System.out.println("shaan Inside processRequest");
int width = 150;
int height = 50;
//Random string generation happens
Random r = new Random();
int length = 6;
System.out.println("shaan Creating string parameter");
StringBuffer captchaStringBuffer = new StringBuffer();
for (int i = 0; i < length; i++) {
int baseCharNumber = ((r.nextInt((500 - 1) + 1) + 1) % 62);
int charNumber = 0;
if (baseCharNumber < 26) {
charNumber = 65 + baseCharNumber;
} else if (baseCharNumber < 52) {
charNumber = 97 + (baseCharNumber - 26);
} else {
charNumber = 48 + (baseCharNumber - 52);
}
captchaStringBuffer.append((char) charNumber);
}
String captchaString = captchaStringBuffer.toString();
System.out.println("The random string generated is : " + captchaString);
char[] s3 = captchaString.toCharArray();
System.out.println("shaan1");
//Converting Captcha String to Image
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bufferedImage.createGraphics();
System.out.println("shaan2");
Font font = new Font("Georgia", Font.BOLD, 18);
g2d.setFont(font);
System.out.println("shaan3");
RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
System.out.println("shaan4");
rh.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHints(rh);
System.out.println("shaan5");
GradientPaint gp = new GradientPaint(0, 0, Color.red, 0, height / 2, Color.black, true);
g2d.setPaint(gp);
g2d.fillRect(0, 0, width, height);
g2d.setColor(new Color(255, 153, 0));
System.out.println("shaan6");
String captcha = String.copyValueOf(s3);
System.out.println("shaan7");
int x = 0;
int y = 0;
for (int i = 0; i < s3.length; i++) {
x += 10 + (Math.abs(r.nextInt()) % 15);
y = 20 + Math.abs(r.nextInt()) % 20;
g2d.drawChars(s3, i, 1, x, y);
}
g2d.dispose();
System.out.println("shaan8");
System.out.println("shaan9");
//Sending Image in output
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", baos);
byte[] imageData = baos.toByteArray();
System.out.println("shaan10" + captcha);
request.getSession(true).setAttribute("captcha", captcha);
System.out.println("shaan11");
baos.flush();
baos.close();
System.out.println("The imageData is :" + imageData);
return Response.ok(imageData, "image/png").build();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("In Error Catch block");
e.printStackTrace();
return Response.status(Status.BAD_REQUEST).build();
}
}
}
然后你可以像这样使用图像:
<!DOCTYPE html>
<html>
<body>
<h1>Hello World!</h1>
<img id="captchaImage" alt="muh" src="/YOUR_REST_PATH/reCaptchaImg"/>
</body>
</html>
推荐阅读
- windows - 禁用切换到 windows 和 mac 上的不同应用程序
- consul - 如何设置单节点 Consul 服务器/客户端?
- azure-devops - 源链接无法从私有 azure 符号服务器下载 nuget 的源文件,使用了错误的域 dev.azure.com/raw/
- c# - 使用 C# Azure Datalake Gen1 客户端的间歇性错误“底层连接已关闭”
- opencv - 在 Linux 上将 OpenCL 与英特尔超高清显卡一起使用
- javascript - Firebase 实时数据库 - 订阅 .on() 不会在客户端触发
- django - 在将 python2 项目移植到 python3 时,mobileesp 的中间件出现错误
- jmeter - 内部服务器错误 - http://localhost:1080/webTours/home.html
- java-9 - jdk9 maven编译错误:模块从A和B读取包
- sql - SQL 查询根据该范围的行之前和之后的记录转换记录集或范围