I have several servlets, which
- take JSON-encoded requests as inputs,
- process them and
- return responses to the client as JSON-encoded objects.
Up to now I used Android as client (sample Android code see below).
Now I want to write a plain old Java program, which would send requests and receive the responses (do the same as the Android code). For this purpose I wrote a Java test (code see below, section Java code) and ran it.
At the client side I get this error:
21:43:38.930 [main] ERROR r.a.c.t.TestAcceptanceProcedure1 - 
java.io.IOException: Server returned HTTP response code: 405 for URL: http://myserver/myapp/rest/GetUserIdService
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441) ~[na:1.6.0_23]
    at testclient.TestAcceptanceProcedure1.test(TestAcceptanceProcedure1.java:47) ~[test-classes/:na]
In the server log, I see this message:
WARNING: No operation matching request path "/myapp/rest/GetUserIdService" is found, Relative Path: /, HTTP Method: GET, ContentType: */*, Accept: text/html,image/gif,image/jpeg,*/*,*/*;q=.2,. Please enable FINE/TRACE log level for more details
Question: How should I change my Java test to fix this error?
Note that the server is up and running (when I execute the Android code, it works).
Android code:
Sending the request and receiving the response:
final GetSimulationStatusRequest request = new GetSimulationStatusRequest();
final String json = Utils.convertToJson(request, getClass());
final String serverUrl = Utils.getServerUrl(this, "GetSimulationStatusService");
final IGetSimulationStatusAsyncTask getSimulationStatusTask = 
        asyncTaskFactory.createGetSimulationStatusAsyncTask(getWebServiceHelper());
Utils.setRequestAndServerUrl(json, serverUrl, getSimulationStatusTask);
final GetSimulationStatusResponse simulationStatusReponse = 
        getSimulationStatusTask.get();
Utils.convertToJson:
public static String convertToJson(final Object aRequest, Class<? extends Activity> aClass) {
    final ObjectMapper mapper = new ObjectMapper();
    String json = null;
    try {
        json = mapper.writeValueAsString(aRequest);
    } catch (final JsonProcessingException exception) {
        Log.e(aClass.getSimpleName(), exception.getLocalizedMessage(),
                exception);
    }
    return json;
}
Utils.setRequestAndServerUrl:
public static void setRequestAndServerUrl(final String aJson,
        final String aServerUrl, final IAsyncTask aTask) {
    aTask.addNameValuePair("request", aJson);
    aTask.sendRequest(new String[] { aServerUrl });
}
GetSimulationStatusAsyncTask:
public class GetSimulationStatusAsyncTask 
    extends AsyncTask<String, String, GetSimulationStatusResponse> 
    implements IGetSimulationStatusAsyncTask {
    private static final String TAG = GetSimulationStatusAsyncTask.class.getSimpleName();
    private IWebServiceTaskHelper helper;
    private ICcpResponseParser<GetSimulationStatusResponse> responseParser = 
            new CcpResponseParser<GetSimulationStatusResponse>();
    public GetSimulationStatusAsyncTask(final IWebServiceTaskHelper aHelper) {
        helper = aHelper;
    }
    @Override
    public void addNameValuePair(final String aName, final String aValue) {
        helper.addNameValuePair(aName, aValue);
    }
    @Override
    protected GetSimulationStatusResponse doInBackground(String... aArgs) {
        return (GetSimulationStatusResponse)Utils.processResponse(this.helper, TAG, responseParser, 
                GetSimulationStatusResponse.class, aArgs);
    }
    @Override
    public void sendRequest(final String[] aArgs) {
        execute(aArgs);
    }
}
Java code:
@Test
public void test() throws JsonProcessingException, MalformedURLException {
    final GetUserIdRequest request = new GetUserIdRequest();
    request.setDeviceId("PC1");
    final String requestAsString = convertToJson(request);
    final String serverUrl = getServerUrl("GetUserIdService");
    final URL url = new URL(serverUrl);
    HttpURLConnection connection = null;
    InputStream inputStream = null;
    try {
        connection = (HttpURLConnection) url.openConnection();
        connection.addRequestProperty("request", requestAsString);
        connection.connect();
        inputStream = connection.getInputStream();
        final String responseAsString = IOUtils.toString(inputStream);
        LOGGER.debug("responseAsString: " + responseAsString);
    } catch (final IOException exception) {
        LOGGER.error("", exception);
    }
    finally
    {
        IOUtils.closeQuietly(inputStream);
    }
}
private String convertToJson(final GetUserIdRequest aRequest) throws JsonProcessingException {
    final ObjectMapper mapper = new ObjectMapper();
    return mapper.writeValueAsString(aRequest);
}
private String getServerUrl(final String aServiceName)
{
    return "http://myserver.com/myapp/rest/" + aServiceName;
}
Update 1 (09.10.2013 12:23 MSK):
@Path("/GetSimulationStatusService")
public class GetSimulationStatusService extends BaseCcpService  {
  private GetSimulationStatusRequestParser requestParser = 
      new GetSimulationStatusRequestParser();
  @POST
  @Produces("text/plain")
  public String getSimulationStatus(@FormParam("request") final String aRequestJson) 
      throws JsonProcessingException
  {
    final GetSimulationStatusRequest request = requestParser.convert(aRequestJson);
    final GetSimulationStatusResponse response = new GetSimulationStatusResponse();
    response.setRequestId(request.getId());
    response.setCycle(getPersistence().getCurrentCycle(request.getUserId()));
    response.setLabourForce(getPersistence().getLabourForceSimulationParameter(
        request.getUserId()));
    return getObjectMapper().writeValueAsString(response);
  }
}
Update 2 (09.10.2013 20:48 MSK): When I change the code like shown below, I get 500 HTTP response. At the server side, the aRequest argument of the method GetUserIdService.getUserId is null.
        connection = (HttpURLConnection) url.openConnection();
        connection.addRequestProperty("request", requestAsString);
        connection.setRequestMethod("POST"); // Added this line
        connection.connect();
Update 3 (09.10.2013 23:15): This one works:
@Test
public void test() throws JsonProcessingException, MalformedURLException 
{
    final GetUserIdRequest request = new GetUserIdRequest();
    request.setDeviceId("PC1");
    final String requestAsString = convertToJson(request);
    final String serverUrl = getServerUrl("GetUserIdService");
    final URL url = new URL(serverUrl);
    HttpURLConnection connection = null;
    InputStream inputStream = null;
    OutputStream outputStream = null;
    try {
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setDoOutput(true);
        connection.connect();
        outputStream = connection.getOutputStream();
        IOUtils.write("request=" + requestAsString, outputStream);
        inputStream = connection.getInputStream();
        final String responseAsString = IOUtils.toString(inputStream);
        LOGGER.debug("responseAsString: " + responseAsString);
    } catch (final IOException exception) {
        LOGGER.error("", exception);
    }
    finally
    {
        IOUtils.closeQuietly(inputStream);
        IOUtils.closeQuietly(outputStream);
    }
}
 
     
    