0

Я создаю JSON RPC в игре 2.1. Чтобы вызвать надлежащие методы, диспетчер RPC использует отражение для создания и вызова экземпляра метода класса по имени.Возможно ли в Play 2.1 преобразовать JsValue в экземпляр класса case, если вы знаете только имя класса case во время выполнения?

Сейчас метод RPC выглядит следующим образом:

def create(obj: JsValue) = { 
    val menu: Menu = Json.fromJson[Menu](obj).get 
    collection.insert(menu).map(r => toDirectResult(r)) 
    } 

    def createCustom(obj: JsValue) = { 
    val menu: Menu = Json.fromJson(obj)(Menu.customFormat).get 
    collection.insert(menu).map(r => toDirectResult(r)) 
    } 

То, что я хотел бы сделать это, чтобы иметь возможность определить методы RPC, как это:

def create(menu: Menu) = { 
    collection.insert(menu).map(r => toDirectResult(r)) 
    } 

Проблема заключается в том, что Диспетчер RPC знает только во время выполнения, который должен вызывать метод с именем «create» в классе с именем «Menus», и он имеет значение аргумента, передаваемого методу как JsValue. Благодаря отражению я могу узнать количество аргументов и их типы для метода RPC. Когда тип аргумента является классом case, как преобразовать JsValue в экземпляр класса case, используя неявный Formatter (или Reader), определенный в сопутствующем объекте класса case?

Для метода createCustom я понимаю, что нет «волшебного» решения, но с тех пор, как я начал изучать Scala, я обнаружил, что с этим языком программирования мало что невозможно. Можно ли использовать аннотацию или что-то подобное, чтобы указать Formatter, который не является неявным?

ответ

0

После дальнейшего тщательного рассмотрения я решил, что отражение действительно нет правильного решения для моей проблемы. В момент компиляции ему не хватает безопасности типов и правильной отчетности об ошибках, сложнее отлаживать и влиять на производительность. И у меня есть вся информация, необходимая для генерации кода во время сборки.

К сожалению, я не могу использовать Play Маршрутизатор, потому что для диспетчера JSON RPC маршрутизация зависит от тела запроса, которая недоступна во время маршрутизации воспроизведения. Но по сути диспетчер RPC делает то же самое, что и роутер Play. Поэтому на данный момент я просто собираюсь вручную кодировать маршруты RPC, а затем проблема в вопросе решена. В будущем я планирую написать плагин SBT, который автоматически сгенерирует код диспетчера, аналогичный игровому маршрутизатору.

0

Вы должны реализовать PathBinder ... это должно помочь http://www.richard-foy.fr/blog/2012/04/09/how-to-implement-a-custom-pathbindable-with-play-2/

+0

К сожалению, это не сработает. Методы RPC не являются действиями внутри контроллера, чтобы иметь возможность сопоставлять их с маршрутами. То, что я делаю, - это реализация [ExtDirect] (http://www.sencha.com/products/extjs/extdirect), поэтому клиентская сторона вызывает только один URL-адрес, а все остальное опубликовано как JSON. – dcb