将 HTML 画布图像传递给控制器​​方法时的空指针

Posted

技术标签:

【中文标题】将 HTML 画布图像传递给控制器​​方法时的空指针【英文标题】:Nullpointer when passing HTML canvas image to Controller method 【发布时间】:2014-07-15 11:14:20 【问题描述】:

我正在尝试在上传到服务器的画布元素中获取由网络摄像头拍摄的照片。 我正在使用 Play Framework 1.2.5.3,并且我的 html 代码如下:

<canvas id="canvas"  ></canvas> 
<button id="snap" onClick="testIT()">Snap Photo</button>

应该在画布中获取图像并上传的表单:

<form action="@Drivers.addPhoto2" method="POST" enctype="multipart/form-data">
<input type="file" name="f1" id="dp" />
<input type="submit" name="submit" value="Upload" />
</form>

当点击“snap”按钮时,会调用 testIT() 方法:

function testIT() 
window.alert("testing...");

var image = new Image();
var canvas = canvas = document.getElementById("canvas");

image.src = canvas.toDataURL("image/png");
window.alert("varialbles created");

document.getElementById('dp').value = image;
window.alert("all done");

在控制器中是这样的:

@Util
private static void addPhoto(Object driverPhoto) 
    System.out.println("addphoto statede");
    if (driverPhoto == null) 
        System.out.println("is null");
        //return;
     else 
        System.out.println("not null");
    

    System.out.println("is class: = " + driverPhoto.getClass());
    Driver driver = User.find("byEmail", Security.connected()).first();
    driver._save();
    index();


public static void addPhoto2(Object f1) 
    System.out.println("photo2 started");
    addPhoto(f1);

现在,当点击“snap”按钮时,图片被绘制(来自网络摄像头,这部分工作)并显示在画布中。然后图片应该以表格形式发送到 INPUT 并从那里上传到服务器,在该服务器中创建新图片(类型:Blob)并将其添加到驱动程序。 实际发生的是:图片是在画布中绘制的,当我点击上传按钮时,调用了 addPhoto2 方法,但随后我在 addPhoto 中得到了一个空指针异常。这里是完整的错误信息:

请求 POST /drivers/addphoto2 的内部服务器错误 (500)

执行异常(在 /app/controllers/Drivers.java 第 56 行附近) NullPointerException 发生:null

play.exceptions.JavaExecutionException 在 play.mvc.ActionInvoker.invoke(ActionInvoker.java:237) 在 Invocation.HTTP Request(Play!) 引起: java.lang.NullPointerException 在 控制器.Drivers.addPhoto(Drivers.java:56) 在 controllers.Drivers.addPhoto2(Drivers.java:64) 在 play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:557) 在 play.mvc.ActionInvoker.invoke(ActionInvoker.java:508) 在 play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:484) 在 play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:479) 在 play.mvc.ActionInvoker.invoke(ActionInvoker.java:161) ... 1 更多

我做错了什么?

【问题讨论】:

【参考方案1】:

如果您查看手册的Advanced bindings 部分,他们会注意到上传的文件将绑定到File 对象。

使用 Play 可以轻松上传文件。使用 multipart/form-data 编码请求将文件发布到服务器,然后使用 java.io.File 类型检索文件对象。

当我获取您的代码并使用addPhoto2f1 参数作为File 对其进行测试时,它工作得非常好。使用f1 作为Object,不会设置参数(因此是null)。我猜当您将文件参数指定为对象并拒绝设置它时,自动播放参数绑定过程会变得混乱。

【讨论】:

谢谢!我刚刚将所有内容从对象更改为文件,但我仍然得到相同的 NullPointerException。 @Paperman 如果您在同一行上遇到完全相同的异常,则肯定是其他地方出了问题,因为在我的测试应用程序(由您发布的代码制成)中,该更改修复了它。我的测试应用程序和您的代码之间唯一的大区别是我注释了 addPhoto 的最后 3 行,因为我没有模型。 @Paperman 我认为您现在遇到的问题与 JPA 方面有关。你如何将照片添加到你的模型中(我在这里的代码中没有看到它)? 我刚刚意识到,当调用 testIT() 方法时,没有执行以下行:document.getElementById('dp').value = image;。这意味着输入元素的值实际上可能为空。我试图用这行代码做的是将画布中的图像转换为输入元素中的文件。我该如何解决这个问题? @Paperman 啊,我专注于 Java 方面。据我所知,(出于明显的安全原因)不可能触及input[type='file'] 元素的值。您可以尝试使用隐藏的输入字段并将数据作为二进制或 dateurl 发送。另一种方法是使用 ajax 函数将 Blob 直接发送到 Play。

以上是关于将 HTML 画布图像传递给控制器​​方法时的空指针的主要内容,如果未能解决你的问题,请参考以下文章

在 Core Data 中的相关实体之间传递数据时的空值

如何在不复制的情况下将画布 imageData 传递给 emscripten c++ 程序?

如何将html5画布上的点击事件传递给兄弟画布元素上的事件监听器

Emscripten将uint8_t数组传递给javascript?

HTML 5 Canvas] 调整大小时的图像质量

将 qr 图像传递给另一个视图控制器