Немного покопавшись, я быстро обнаружил, что в основном есть две опции:
Опция 1
Вы передаете «объект-обертку», содержащий все остальные параметры, службе.Возможно, вам потребуется аннотировать этот класс-оболочку аннотациями JAXB, такими как @XmlRootElement, чтобы он работал с провайдером на основе Jettison, но если вы используете Джексона вместо него, в этом нет необходимости.Просто установите тип контента на правильный тип, и будет вызван правильный читатель тела сообщения.Конечно, это будет работать только для служб типа POST (AFAIK).
Пример
Это всего лишь пример преобразования службы, упомянутой в исходном вопросе, в службу с использованием объекта-оболочки.
@Service("myService")
class RestService {
@POST
@Produces("application/json")
@Path("/fooBar")
public Result fooBar(
/**
* Using "" will inject all form params directly into a ParamsWrapper
* @see http://cxf.apache.org/docs/jax-rs-basics.html
*/
@FormParam("") FooBarParamsWrapper wrapper
) throws WebServiceException {
doSomething(wrapper.foo);
}
}
class ParamsWrapper {
double foo, bar;
MyComplexObject object;
}
Опция 2
Вы можете предоставить специальный формат строки, в который вы упаковываете свои объекты, а затем реализуете конструктор, принимающий строку, static valueOf (String s) или static fromString (Строка s) в классе, который возьмет эту строку и создаст из нее объект.Или совсем аналогично, создайте ParameterHandler, который делает то же самое.
AFAIK, только вторая версия позволит вам вызывать ваши сервисы из браузера, используя JSONP (поскольку JSONP - это трюк, ограниченный GET).Я выбрал этот маршрут, чтобы иметь возможность передавать массивы сложных объектов в URI.
В качестве примера того, как это работает, возьмем следующий класс домена и службу
Пример
@GET
@Path("myService")
public void myService(@QueryParam("a") MyClass [] myVals) {
//do something
}
class MyClass {
public int foo;
public int bar;
/** Deserializes an Object of class MyClass from its JSON representation */
public static MyClass fromString(String jsonRepresentation) {
ObjectMapper mapper = new ObjectMapper(); //Jackson's JSON marshaller
MyClass o= null;
try {
o = mapper.readValue(jsonRepresentation, MyClass.class );
} catch (IOException e) {
throw new WebApplicationException()
}
return o;
}
}
URI http://my-server.com/myService?a={"foo":1, "bar":2}&a={"foo":100, "bar":200}
в этом случае будет десериализован в массив, состоящий из двух объектов MyClass.
2019 комментарий: Видя, что этот ответ все еще получает некоторые попадания в 2019 году,Я чувствую, что должен прокомментировать.Оглядываясь назад, я бы не рекомендовал вариант 2, поскольку выполнение этих шагов только для того, чтобы иметь возможность выполнять вызовы GET, добавляет сложности, которая, вероятно, того не стоит.Если ваш сервис принимает такие сложные входные данные, вы, вероятно, не сможете использовать кэширование на стороне клиента из-за количества перестановок вашего ввода.Я бы просто настроил правильные заголовки Cross-Origin-Sharing (CORS) на сервере и POST-ввод.Затем сконцентрируйтесь на кэшировании всего, что можете на сервере.