Tom O'Brien Tom O'Brien - 1 month ago 12
reST (reStructuredText) Question

JAX-RS GET and DELETE giving 405 Error

I have implemented a method to upload an audio file by posting to a Jersey JAX-RS REST backend. This works fine. However, when I try to implement the DELETE audio file method, it gives me the following error:

HTTP 405 Method Not Allowed


I can't for the life of me see what is wrong - i assume it might be something trivial that I am blind to, as I've done many DELETES before and they have worked. I've also tried to implement a simple dummy GET method and that too gives the same error.

The file upload is done using an angularjs directive called ng-file-upload.
It is uploaded successfully using the following url:

file.upload = Upload.upload({
url: 'http://localhost:8080/pododdle/webapi/auctions/' + bid.auction_id + '/uploads?category_id=' + bid.category_id,
data: {file: file}
});


An example URL for the upload would then be:

http://localhost:8080/pododdle/webapi/auctions/1/uploads?category_id=2


I have tried using POSTMAN to use the DELETE incase my frontend code was wrong. The url supplied was:

http://localhost:8080/pododdle/webapi/auctions/1/uploads


Here is the code for the entire 'uploads' Resource, both DELETE and POST. As you can see the DELETE is only a dummy method, with no real work done. Also, the upload Resource is a subresource of the 'auctions' resource.

@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class UploadResource {

private static final Logger log = Logger.getLogger(UploadResource.class);
AuctionService auction_service = new AuctionService();

@DELETE
public Response deleteAudio(@PathParam("auction_id") int auction_id) {
System.out.println("inside deleteAudio");
return Response.ok().build();
}

//this uploads the audio file, stores it to disk, and then saves the file-path to the auction
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces("text/html")
public Response uploadAudio(@PathParam("auction_id") int auction_id, @QueryParam("category_id") int category_id,
@FormDataParam("file") InputStream fileInputString, @FormDataParam("file") FormDataContentDisposition fileInputDetails) {

//We need to get the value of the audio root directory
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Properties properties = new Properties();
try {
properties.load(classLoader.getResourceAsStream("pododdle.properties"));
} catch (IOException e) {
log.error("Error getting the audio root directory location when uploading the audio: " + e.getMessage());
e.printStackTrace();
}
String auctionAudio = "audio/category/" + category_id + "/auction/" + auction_id + "/" + fileInputDetails.getFileName();
String audioFileName = properties.getProperty("audioRootDirectory") + auctionAudio;

NumberFormat myFormat = NumberFormat.getInstance();
myFormat.setGroupingUsed(true);

try {
File audioFile = new File(audioFileName);
File parent = audioFile.getParentFile();
if(!parent.exists() && !parent.mkdirs()) {
return Response.status(501).entity("Error creating directory when uploading the audio to the server. Please try again in a few moments").build();
}
OutputStream out = new FileOutputStream(audioFile, false);
byte[] buffer = new byte[1024];
int bytes = 0;
long file_size = 0;

while((bytes = fileInputString.read(buffer)) != -1) {
out.write(buffer, 0, bytes);
file_size += bytes;
}
out.flush();
out.close();

log.info(String.format("Uploading Audio file for category: " + category_id + ", fileSize: %s", myFormat.format(file_size)));
} catch (IOException ioe) {
System.out.println("error uploading audio file to server: " + ioe.toString());
return Response.status(501).entity("Error uploading the audio to the server. Please try again in a few moments").build();
}

//now updating the auction with the audio path in the database and return the updated auction
return Response.ok(auction_service.updateAuction(auction_id, auctionAudio).toString()).build();
}


}

The Auction resource looks like this:

@Path("/auctions")
public class AuctionResource {

//creating sub-resource for auction bids
@Path("/{auction_id}/uploads")
public UploadResource getUploadResource()
{
return new UploadResource();
}
}

Answer

It looks like this error was caused by the project not building properly. Upon inspection of the buildpath, it seemed two jar files were mysteriously missing! They were:

jersey-media-multipart-2.21.1.jar
mimepull-1.9.3.jar

I have no idea how the jar files were deleted from the /lib directory of the glassfish server, maybe I shouldn't have drunk that extra bottle of whiskey. Once they were added back in, everything suddenly worked hunky dory. A little baffled by the error - i would have thought it would give a compile error if the jar wasn't available. Anyhow, 5 days lost due to another annoying error.

Comments