Basic file uploading fails
I am not able to perform any uploading operations on the server. Contrary to "one of the five cool things you can do with play", the following does not seem to work:
public static void doSingleFileUpload(
Long id, @Required java.io.File upload, String description, String title
) {
Score score = Score.findById(id);
try {
score.files.add(new File(doFileUpload(new FileInputStream(upload), score), title));//PLAY crashes here, with a nullpointer exception on the upload parameter
} catch (IOException ex) {
//TODO: do something nice
}
score.save();
}
doFileUpload
looks like this:
@Check("registered")
private static String doFileUpload(InputStream is, Score score) throws IOException {
//get Score from db
//get dir if present
java.io.File dir = new java.io.File("/public/uploads/" + play.templates.JavaExtensions.slugify(score.title));
//if not, create
if (!dir.exists()) {
dir.mkdirs(); //create new dir if not present
}
//create file on server
java.io.File newfile = new java.io.File(dir, "testfile.txt");
OutputStream os = new FileOutputStream(newfile);
IOUtils.copy(is, os);
return newfile.getAbsolutePath();
}
With this view:
<!-- ... -->
<form action="@{ScoreController.doSingleFileUpload()}" method="POST" enctype="multipart/form-data">
<input type="hidden" name="id" value="${score.id}" />
<input type="file" id="upload" name="upload" />
<input type="text" name="description" />
<input type="hidden" name="title" value="${score.title}" />
<input type="submit" value="submit" />
</form>
Why is upload
null? I fo开发者_运维技巧und a similar problem here. But when I look at the headers after the POST, there is very little information there, except for the playsession key...
What am I doing wrong?
I am testing with FF4 and using Play 1.1.1.
EDIT: This sample application works in both 1.1.1 and 1.2.
Controller:
public class Application extends Controller {
public static void index() {
File dir = new File(Play.applicationPath+File.separator+"public"+File.separator+"uploads");
if (!dir.exists() && dir.isDirectory()) {
renderText("something went wrong");
} else {
String[] files = dir.list();
if (files != null) {
render(dir);
} else {
render();
}
}
}
public static void upload(File upload) throws FileNotFoundException, IOException {
File dir = new File(Play.applicationPath+File.separator+"public"+File.separator+"uploads");
if (!dir.exists()) {
dir.mkdirs();
}
File newfile = new File(dir, upload.getName());
FileInputStream fis = new FileInputStream(upload);
FileOutputStream fos = new FileOutputStream(newfile);
IOUtils.copy(fis, fos);
index();
}
}
View:
#{extends 'main.html' /}
#{set title:'Home' /}
#{form @Application.upload(), enctype:'multipart/form-data'}
<input type="file" name="upload" />
<input type="submit" />
#{/form}
#{if (dir.list()!=null)}
<ul>
#{list items:dir.list(), as:'file'}
<li><a href="public/uploads/${file}">${file}</a></li>
#{/list}
</ul>
#{/if}
Now the questions is: What is the difference between the applications, except for the fact that the first one has more parameters...
Thanks for the help everyone so far!
greetings, jasper
Does that compile? You’re passing a java.io.File
object to doFileUpload
, whose first parameter is an InputStream
.
Not sure why your code is not working, but I got something similar to work by using Blob instead of File.
public static void update(long userId,
String aboutMyself,
String location,
Blob profilePicBlob) {
UserProfile userProfile = UserProfile.find("select distinct upr from UserProfile upr where upr.user.id = ?", userId).first();
if(profilePicBlob != null) {
//TODO: Delete the old profile pic
userProfile.profilePic = new Pic(profilePicBlob).save();
}
userProfile.aboutMyself = aboutMyself;
userProfile.location = location;
userProfile.save();
show(userId);
}
@Entity
public class Pic extends Model {
public Blob image;
public Pic(Blob image) {
this.image = image;
}
}
#{form @UserProfileC.update(userProfile.user.id), enctype:'multipart/form-data'}
<div>
<div>About Myself:</div>
<textarea rows="10" cols="80" name="aboutMyself">${userProfile.aboutMyself</textarea>
</div>
<div>
<div>Location</div>
<input type="text" name="location" value="${userProfile.location}"/>
</div>
<div>
<input type="file" name="profilePicBlob" />
<label>${userProfile.profilePic == null ? 'Upload' : 'Change'} profile pic</label>
</div>
<div>
<input type="submit" value="Submit" id="postComment" />
</div>
#{/form}
精彩评论