views:

89

answers:

2

Hey all,

So, I've got a pretty simple RESTful jersey webservice, and I'm wanting to call it from my javascript code. I have no problem executing a GET request, but for some reason, when I execute a PUT, I get back a "415 Unsupported Media Type" error. Any idea what I'm doing wrong?

Here's my webservice :

package servlet;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.JAXBElement;

import com.mycompany.www.hudsonsemaphore.HudsonResult;
import com.mycompany.www.hudsonsemaphore.SemaphoreConstants;

@Path("/HudsonSemaphore")
public class HudsonSemaphore {
    static private HudsonResult lastResult;
    static private Object RESULT_LOCK = new Object();       

    @PUT
    @Consumes({MediaType.APPLICATION_JSON})
    static public void setResult(JAXBElement<HudsonResult> result) {        
        synchronized(RESULT_LOCK) {
            lastResult=result.getValue();
        }       
    }   

    @GET
    @Produces({MediaType.APPLICATION_JSON})
    public HudsonResult getLastResult() {
        HudsonResult toReturn;

        if(lastResult!=null) {
            synchronized(RESULT_LOCK) {
                toReturn = lastResult;
                lastResult=null;
            }
        }
        else {
            toReturn = SemaphoreConstants.NULL_HUDSON_RESULT;
        }

        return toReturn;
    }       
}

Here's my annotated JAXBElement :

package com.mycompany.www.hudsonsemaphore;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name="hudsonResult")
@XmlType(propOrder = { 
    "message", "success"
})
public class HudsonResult {
    private boolean success;
    private String message; 

    public HudsonResult() {
        success=false;
        message=null;
    }

    public HudsonResult(String message, boolean success) {
        this.success = success;
        this.message = message;     
    }

    @XmlElement
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message=message;
    }

    public void setSuccess(boolean success) {
        this.success=success;
    }

    @XmlElement
    public boolean isSuccess() {
        return success;
    }

    public boolean equals(HudsonResult result) {
        return(result.success == success && result.message.equals(message));
    }

    public String toString() {
        return "Success : [" + String.valueOf(success) + "] Message : [" + message + "]";
    }
}

And finally, here's my javascript code :

<script type="text/javascript" src="/system/workplace/resources/ext/ext-base.js"></script>
<script type="text/javascript" src="/system/workplace/resources/ext/ext-all.js"></script>

<script type="text/javascript">

function pollSemaphore() {
    Ext.Ajax.request({
        url : 'http://localhost:8081/leadcapture/rest/HudsonSemaphore',
        method: 'GET',
        success: 
            function(result, request) {
                var jsonData = Ext.util.JSON.decode(result.responseText);

                if(jsonData.success=='true') {
                    alert('SUCCESS : ' + jsonData.message);
                }
                else {
                    alert('NOT SUCCESS : ' + result.responseText);  
                }
            },
        failure: 
            function(result, request) {
                alert('Teh fail : ' + result.responseText);
            }
    });
}

function pushSemaphore() {
    Ext.Ajax.request({
        url : 'http://localhost:8081/leadcapture/rest/HudsonSemaphore',
        method: 'PUT',
        params: {message : 'Brand new car!', success : 'true'},
        success: 
            function(result, request) {
                alert('YOU RULE!');
            },
        failure: 
            function(result, request) {
                alert('Teh fail : ' + result.responseText);
            }
    });
}

</script>

<input type="button" onclick="pushSemaphore()" value="Push"/> <br/>
<input type="button" onclick="pollSemaphore()" value="Poll"/> <br/>

Thanks for taking a look!

A: 

Okay, I think I figured this one out. Apparently, you want to give the Ext.Ajax.request method a jsonData parameter instead of a params parameter. This is really bizarre, because all the examples tell you to use the params parameter, which gives me the 415 error. Anyway, the working version of the pushSemaphore() function looks like so :

function pushSemaphore() {
    Ext.Ajax.request({
        url : 'http://localhost:8081/leadcapture/rest/HudsonSemaphore',
        method: 'PUT',
        jsonData: {message : 'Brand new car!', success : 'true'},
        success: 
            function(result, request) {
                alert('YOU RULE!');
            },
        failure: 
            function(result, request) {
                alert('Teh fail : ' + result.responseText);
            }
    });
}

So, it's good that I've got this working, but it's still a mystery to me why this works, and why it fails when I follow the examples in the documentation. Any thoughts on the matter?

A: 

Since your web service code expecting JSON ---@Consumes({MediaType.APPLICATION_JSON})---- that's why it failed when your request comes through with different media type format. Your fixed works because you did set your request content type to JSON data.

Kyle
Good call. I think what happened was that the original example code I read used the params field and not the jsonData field, and that threw me off.