Как я могу вернуть изображение из метода сервиса REST в браузер - PullRequest
0 голосов
/ 06 октября 2018

Цель - я создаю свою собственную капчу, в которой у меня есть клиент, с которого я буду делать REST вызов на бэкэнде Java.В бэкэнде у меня есть программа, которая сгенерирует случайную строку, а затем она будет преобразована в изображение, которое затем будет возвращено на сторону клиента для рендеринга, чтобы пользователь мог вводить те же символы, что и на изображении, а капчу можноподтверждено.

Подход - у меня есть вызов REST, который возвращает javax.ws.rs.core.Response, и в этом я привязываю свой CaptchaImage, чтобы он мог быть отображен в браузере.Этот подход несколько похож на Как вернуть изображение PNG из метода сервиса REST Джерси в браузер

Код: ICaptchaServlet.java - Интерфейс

import java.io.IOException;
import java.security.GeneralSecurityException;

import javax.servlet.http.*;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;

public interface ICaptchaServlet{

    public Response processRequest(@Context HttpServletRequest req) throws GeneralSecurityException, IOException;

    @GET
    @Path("/getChallenge")
    public Response doGet(@Context HttpServletRequest req) throws GeneralSecurityException;
}

CaptchaServlet.java

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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
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.Response;

//Internal Rest Service annotation which it picks up fine
@Named("CaptchaServlet")
@Path("/reCaptchaImg")
@Produces("image/png")
public class CaptchaServlet implements ICaptchaServlet{

    @Override
    public Response processRequest(HttpServletRequest request) throws GeneralSecurityException, IOException {
        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);
        // uncomment line below to send non-streamed
        //return Response.ok(imageData).build();

        // uncomment line below to send streamed
         return Response.ok(new ByteArrayInputStream(imageData)).build();
    }

    @Override
    public Response doGet(HttpServletRequest request) throws GeneralSecurityException {
        System.out.println("shaan inside doGet");
        Response response = null;
        try {
            response =  processRequest(request);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return response;
    }

}

Проблема: я поместил в системный журнал заявления, чтобы помочь отследить проблему лучше.Когда я выполняю это, вызов службы Rest не возвращает SUCCESS и переходит к функции обратного вызова ERROR.Изображение не отображается.Я пробовал оба следующих подхода:

// uncomment line below to send non-streamed
//return Response.ok(imageData).build();

// uncomment line below to send streamed
// return Response.ok(new ByteArrayInputStream(imageData)).build();

Журналы:

shaan inside doGet
shaan Inside processRequest
shaan Creating string parameter
The random string generated is : o06k5g
shaan1
shaan2
shaan3
shaan4
shaan5
shaan6
shaan7
shaan8
shaan9
shaan10o06k5g
shaan11
shaan12
The imageData is :[B@3c83339
23:35:49.192 [[ACTIVE] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'] DEBUG o.a.c.ws.policy.PolicyOutInterceptor - No binding operation info.
23:35:49.200 [[ACTIVE] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'] DEBUG o.a.c.j.i.JAXRSOutInterceptor - Response content type is: image/png
23:35:49.213 [[ACTIVE] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'] DEBUG o.a.cxf.ws.addressing.ContextUtils - retrieving MAPs from context property javax.xml.ws.addressing.context.inbound
23:35:49.213 [[ACTIVE] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'] DEBUG o.a.cxf.ws.addressing.ContextUtils - WS-Addressing - failed to retrieve Message Addressing Properties from context
23:35:49.219 [[ACTIVE] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'] DEBUG o.a.c.t.servlet.ServletController - Finished servicing http request on thread: Thread[[ACTIVE] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads]
...