Как я могу предоставить собственный маршаллер для класса SecretData, который применяется только для конечной точки someExternalService?
Ну, AFAIK, вы не можете (см. Примечание № 3). Но вы можете решить свою проблему, используя разделение интересов и создав иерархический дизайн вашего API ... позвольте мне объяснить ...
Предположим, что Data
- это ваш главный объект (это будет то, что вы сейчас называете «обычным» SecretData
), он содержит информацию, которую внутренние (или внешние) службы хотят передать ...
public class Data {
protected int attribA;
...
protected String attribN;
public static Data valueOf(String data) {
// here, you transform the string and set
// the corresponding attributes values
}
}
Затем вы можете определить конечную точку следующим образом:
@GET
@Path(/*...*/)
public someInternalService(@QueryParam("data") Data data) {/*...*/}
Теперь для внешних сервисов вы создаете новый POJO («разделение интересов») следующим образом:
public class EncryptedData extends Data {
// any attribute is inherited from data
// this class does not expose new attributes
/**
* Copy constructor.
*/
EncryptedData(Data data) {
super();
this.attribA = data.attribA;
...
};
public static EncryptedData valueOf(String opaque) {
// here, you transform the encrypted String into
// a regular String, then you call Data.valueOf ...
// example:
String decrypted = decrypt(opaque);
return new EncryptedData( Data.valueOf(decrypted) );
}
}
Тогда ваша конечная точка внешних служб будет выглядеть так:
@GET
@Path(/*...*/)
public someExternalService(@QueryParam("opaque") EncryptedData data) {/*...*/}
ПРИМЕЧАНИЕ: Поскольку экземпляр EncryptedData
IS_A Data
, вы можете передать такой объект любому другому методу, который получает экземпляр Data
в качестве входных данных! Таким образом, вам не нужно делать никаких других преобразований ...
ПРИМЕЧАНИЕ2: очевидно, если вы используете RestEasy в качестве реализации JAXRS, вы можете определить настраиваемый сериализатор String ... см. StringConverter
ПРИМЕЧАНИЕ3: проверка документации restEasy, JAX-RS 2.0 содержит способ создания собственного сериализатора ... см. ParamConverter ... Под В этой стратегии вам потребуется создать два ParamConverter (один для простого SecretData
и один для непрозрачного SecretData
); и фабрика ParameterConverter (реализация интерфейса ParamConverterProvider
) ... если вы проверяете документы интерфейса, интерфейс предоставляет только один метод, и такой метод получает аннотации, примененные к параметру, который (де) сериализуется ... так, вы получите (я думаю) что-то вроде: @QueryParam("data")
или @QueryParam("opaque")
, и на основе этих значений вы можете соответственно создать ParameterConverter!