0

私はRESTサービスを提供するアプリケーションを開発してきました。私はそれに対して実行するいくつかのテスト済みコードを持っており、それが正常に機能するかどうかを確認しています。

ローカルのWeblogic開発サーバーにデプロイされたアプリケーションに対して実行すると、正常に動作します。

ただし、Red Hatマシン上の別のWeblogicサーバーにデプロイすると、400の不正な要求エラーが発生します。

サービスのテストに使用しているクライアントコードは次のとおりです。

    Client client = Client.create();
    //WebResource webResource = client.resource("http://10.1.1.2:7001/NotificationFramework/rest/notifications/createNotification");
    WebResource webResource = client.resource("http://rhvm:7003/NotificationFramework/rest/notifications/createNotification");

    ClientResponse clientResponse = webResource.type("application/json").post(ClientResponse.class, testJsonObject.toString());
    JSONObject response2 = new JSONObject(clientResponse.getEntity(String.class)); 
    System.out.println(response2);

コメントされた行は、私のローカルマシン上の行です。

これが私が得ている応答です:

An error occurred: Server returned HTTP response code: 400 for URL: http://rhvm:7003/NotificationFramework/rest/notifications/createNotification

そして、RESTサービスを提供するコードの抜粋を次に示します。

@Path("/notifications")
public class RestServices {     

    @POST
    @Path("/createNotification")
    @Consumes( {MediaType.APPLICATION_JSON} )
    @Produces( {MediaType.APPLICATION_JSON} )
    public static NotificationResponse createNotification(JAXBElement<Notification> n) {
// do some stuff

return notificationResponse;
}

私はすでに最後に余分な/を入れてみました。そして、Firefox用のRESTClientアドオンでテストしたところ、まったく同じ動作が得られました。

どんな助けでも大歓迎です。

前もって感謝します。

// 編集

私はそれがJAXBElementと関係があることを発見しました。

次のサービスが機能します。

@POST
@Path("testRest3")
@Consumes( {MediaType.APPLICATION_JSON} )
@Produces({MediaType.APPLICATION_JSON})
public static NotificationResponse testRest3() {
    logger.info("yo3");

    return new NotificationResponse(101, "yo");
}

しかし、以下はそうではありません:

@POST
@Path("testRest4")
@Consumes( {MediaType.APPLICATION_JSON} )
@Produces({MediaType.APPLICATION_JSON})
public static NotificationResponse testRest4(JAXBElement<Notification> n) {
    logger.info("yo4");

    return new NotificationResponse(101, "yo");
}

pestrellaが推奨するNotificationクラスを確認したところ、@XmlRootElementが欠落していることがわかりました。これを追加しましたが、まだ問題は解決していません。@Xmlにする必要があるかどうかはわかりませんが、これは初めてです。vogellaからのチュートリアルに従います。

これが私の通知クラスです:

@XmlRootElement
public class Notification {
    private int applicationId;
    private int notificationId;
    private int priority;
    private String message;
    private String detail;
    private String appUrl;

// methods and stuff

}

そして、Firefox用のRESTClientアドオンで送信された本文は次のとおりです。

{"appUrl":"","message":"my message","notificationId":1110001,"detail":"my detail","priority":3,"applicationId":111}
4

1 に答える 1

1

この場合の400応答は、ボディのマーシャリングを解除しているときに、ある種のエラーを示している可能性がありますPOST

を使用して@XMLRootElementも問題ありません。ただし、JAXBをプリミティブ型にアンマーシャリングする際に問題が発生する可能性があります(使用しているバージョンによって異なります)。

JAXBでオブジェクトを非整列化する最も安全な方法は、プリミティブ型の代わりに型Notificationを使用することです。Integerint

@XmlRootElement
public class Notification {
    private Integer applicationId;

    /* and the rest... */
}

また、注釈を使用している場合は、Notificationオブジェクトをラップする必要はありません。ラッパーを削除してみてください。JAXBElement@XmlRootElementJAXBElement

@POST
@Path("testRest")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public static NotificationResponse testRest(Notification n) {
    logger.info("yo!");
    return new NotificationResponse(101, "yo");
}

問題が解決しない場合は、いつでもを使用しMessageBodyReaderてリクエスト本文を手動でアンマーシャリングできます。

JSONリクエストボディに対してこれを行う一般的な方法はMessageBodyReader、GsonやJacksonなどの選択したJSONパーサーを実装して使用することです。

@Provider
@Consumes("application/json")
public class CustomJsonReader<T> implements MessageBodyReader<T> {

    @Override
    public boolean isReadable(Class<?> type, Type genericType,
            Annotation[] annotations,MediaType mediaType) {
        return true;
    }

    @Override
    public T readFrom(Class<T> type, Type genericType, Annotation[] annotations,
            MediaType mediaType, MultivaluedMap<String, String> httpHeaders,
            InputStream entityStream) throws IOException, WebApplicationException {

        /* Convert the request body (passed in as InputStream) to a String.
         * Here I'm using apache commons IOUtils to convert the input stream
         */
        StringWriter writer = new StringWriter();
        IOUtils.copy(entityStream, writer, "UTF-8");
        String json = writer.toString();

        /* Use JSON parser to unmarshal the JSON to a complex object */
        return new Gson().fromJson(json, genericType);
    }
}
于 2013-03-15T18:04:27.967 に答える