Вы можете сделать это, определив интерфейс Deserializer и различные реализации для каждого формата.
К вопросу 1: Это зависит от того, как вы хотите это сделать. Один из способов - использовать одну конечную точку и использовать заголовок Content-Type веб-запроса и выбрать десериализатор на его основе.
Вот пример:
public enum Formats { JSON, CSV, XML }
public interface Deserializer {
Format getFormat();
object deserialize(string input);
}
public JSONDeserializer extends Deserializer {
public Format getFormat() { return Formats.JSON; }
public object deserialize(string input) { .... }
}
public CSVDeserializer extends Deserializer {
public Format getFormat() { return Formats.CSV; }
public object deserialize(string input) { .... }
}
public XMLDeserializer extends Deserializer {
public Format getFormat() { return Formats.XML; }
public object deserialize(string input) { .... }
}
Если вы хотите избежать явного перечисления Format для определения ваших типов, вы можете использовать тип содержимого напрямую как string или MediaType. Это приведет к тому, что ваш интерфейс Deserializer будет тесно связан с вашими обработчиками запросов, что затруднит их использование в других частях кода. Также в качестве альтернативного дизайна вы можете перенести ответственность за проверку в десериализаторе.
public interface Deserializer {
string getContentType();
object deserialize(string input);
}
public JSONDeserializer extends Deserializer {
public string getContentType() {
return "application/json";
}
public object deserialize(string input) { .... }
}
public interface Deserializer {
bool cetDeserialize(string contentType);
object deserialize(string input);
}
public JSONDeserializer extends Deserializer {
public bool cetDeserialize(string contentType) {
return contentType == "application/json";
}
public object deserialize(string input) { .... }
}
Вот как вы его используете.
List<String> mDeserializers = Arrays.asList(
new JSONDeserializer(),
new CSVDeserializer(),
new XMLNDeserializer()
);
Deserializer deserializer = mDeserializers
.stream()
.filter(d => d.getContentType() == contentType)
.findFirst();
// or if you use a specific format:
Deserializer deserializer = mDeserializers
.stream()
.filter(d => d.getFormat() == getFormatFromContentType(contentType))
.findFirst();
deserializer.deserialize(input);
Что касается весны, не пробовал сам, вы можете сделать что-то вроде этого, не указывая расход:
@RequestMapping(value = "/data", method = RequestMethod.POST)
public String process(
@RequestHeader HttpHeaders httpHeaders,
@RequestBody String body){
// get value of content-type header as string
// get serializer based on string value
}
или
@RequestMapping(value = "/data", method = RequestMethod.POST)
public String process(
@RequestHeader(value="Content-Type") String contentType,
@RequestBody String body){
// get serializer based on string value
}