2013-03-15 2 views
0

Я разрабатываю приложение, предоставляющее услугу REST. У меня есть некоторый проверенный код, который я запускаю против него, чтобы убедиться, что он работает нормально.Получение 400 плохих запросов из одного приложения в Weblogic на Red Hat

При работе с приложением, развернутым на моем локальном сервере разработки Weblogic, он отлично работает.

Однако, когда я развернул его на другом сервере Weblogic на машине Red Hat, я получаю 400 ошибок Bad Request.

Вот код клиента я использую для тестирования службы:

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; 
} 

Я уже пытался ставить дополнительный/на конец. И я тестировал его с помощью дополнения RESTClient для Firefox, и я получаю то же самое поведение.

Любая помощь была бы принята с благодарностью.

Заранее спасибо.

// Редактировать

я обнаружил, что это что-то делать с 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 и обнаружили, что @XmlRootElement отсутствует. Я добавил это, но это еще не устранило проблему. Я не уверен, что это будет @Xml .. но я новичок в этом. После tutorial из vogella.

Вот мой Notification класс:

@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 

} 

А вот тело, как представлено с RESTClient дополнения для Firefox:

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

Ваш код выглядит хорошо. Если вы абсолютно уверены, что вы развернули один и тот же код и что ваш тестовый код тот же, я бы сначала посмотрел в ваши журналы Weblogic, чтобы определить, что вызывает ответ «400». Ищите исключения. В зависимости от того, как вы объединили компоненты REST REST, вы можете обнаружить, что ваш 'MessageBodyReader' не может десериализовать входящий элемент' POST', потому что он неверен. Можете ли вы добавить код класса «Уведомление» на вопрос, а также тело 'POST', которое вы отправляете через RESTClient? – pestrella

+0

Ваш комментарий стал намного ближе. Я сделал несколько фиктивных сервисов и включил проблему. Как вы предположили, это связано с тем, как он пытается получить данные из объекта Notification (n). Я просмотрел класс Notification и обнаружил, что «@XmlRootElement отсутствует. Я добавил его, но он все еще не решил проблему (хотя тот факт, что он называется «@XmlRootElement», заставляет меня думать, что это тоже не так ... но я не мог найти «@JsonRootElement ... Я новичок в все это). Я добавил материал, который вы просили увидеть. Спасибо за помощь в этом. Я очень ценю это. –

+0

О, я проверил журналы weblogic, но не исключения, насколько я мог видеть в любом случае. –

ответ

1

400 ответ в данном случае может указывать на какой-то ошибки, в то время как unmarhsalling тело POST.

Использование @XMLRootElement в порядке. Однако у вас могут возникнуть проблемы с тем, чтобы JAXB был unmarshal для примитивных типов (в зависимости от того, какая у вас версия).

Самый безопасный способ получить JAXB для отмены вашего объекта Notification - использовать тип Integer вместо примитива int.

@XmlRootElement 
public class Notification { 
    private Integer applicationId; 

    /* and the rest... */ 
} 

Кроме того, вам не нужно обернуть Notification объект с JAXBElement, если вы используете @XmlRootElement аннотацию. Попробуйте удалить JAXBElement обертку:

@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 и использование анализатора JSON по вашему выбору, такого как Gson или Jackson.

@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); 
    } 
} 
+0

Попробовал сменить int на Integer, но без радости. Любопытно, кстати, почему вы предпочитаете маршалировать себя, а не использовать что-то вроде JAXB? –

+0

Не пытайтесь обернуть объект «Уведомление» с помощью 'JAXBElement', поскольку он избыточен при использовании аннотации' @ XmlRootElement'. Я предпочитаю сортировать объекты самостоятельно, используя Jackson (или GSON) внутри «MessageBodyReader» в сценариях, где требуется большая гибкость. Это немного больше, но если вы решите пойти в этом направлении, то вот как я это сделал в прошлом: http://stackoverflow.com/a/14751029/551467 – pestrella

+0

Я попытался удалить обертку, но все еще не работал , Можете ли вы подумать о какой-либо причине? Подумайте, я просто собираюсь сделать это сам, потому что я немного схожу. Спасибо за ссылку. Если вы отредактируете свой ответ, чтобы сказать только для его маршала, я соглашусь с ним, так как ваши комментарии и ответ помогли мне хотя бы получить решение (даже если это руководство). Я бы очень хотел сделать это автоматически, хотя. –

Смежные вопросы