Comments 67
Но самый большой плюс — поддержка стандартов (Servlet 3.1, JSR-356 для вебсокетов).
Servlet API – это крутой стандарт, но он уже монстроузорный :-(
Servlet API – это не HTTP стандарт, это абстракция над гораздо большим количеством протоколов. С чистым Servlet API крайне неудобно работать. И над ним делают еще парочку абстракций, чтобы добавить удобства. А потом это все выливается в довольно медленный код и раздутый хип.
Servlet API нужно омолаживать; его уже нужно чем-то заменить! Делать какой-то Java HTTP API.
- Нужно оверрайдить нужные http методы сервлетов (doGet, doPost, etc).
- Нужно приводить ServletRequest в HttpServletRequest.
- Нужно самому руками вычитывать энтити из InputStream и парсить их!!
- Нужно так же делать сериализацию энтитей и писать в OutputStream!!
Где же тут удобство?
Фреймворки и дополнительные уровни абстракций появляются потому, что сервлеты в чистом виде – это боль и унижение.
Хотелось бы что-то вроде GWT, чтобы делать интерфейс из компонентов и не думать о джаваскрипте, GWT актуален ещё?
На мой взгляд это такой Delphi в java мире. Legacy думаю еще достаточно много, но вот начинать на нем что-то новое на мой взгляд не надо.
начинать на нем что-то новое на мой взгляд не надо
А можно услышать какие-нибудь аргументы? Просто интересно
Потому что он безнадежно отстал от прогресса.
Например Element.querySelector()
уже более 5 лет доступен в браузерах, а в GWT его так и не поддержали: https://stackoverflow.com/questions/2406002/find-an-element-by-css-selector-in-gwt/3164919
И такие флешбеки при разработке на GWT встречаются регулярно. Хочется заиспользовать какую-нибудь браузерную особенность, а нет – GWT о ней не знает и вызвать не дает. Можно выкрутиться через JSNI, но зачем тогда вообще тащить GWT.
В соседних комментах предлагают Kotlin или Scala.js, в них с актуальностью все получше.
Например Element.querySelector()
уже более 5 лет доступен в браузерах, а в GWT его так и не поддержали
А зачем его вызывать вручную? Я всегда думал, что выбор элементов за меня сделает библиотека виджетов. А сделает она это через JSNI или через overlay-тип — мне какая разница? Конечно, иногда надо напрямую сделать что-то с DOM, но это настолько редко требуется, что кусочек JSNI не проблема написать. Зато остальные 99% кода пишутся на Java без проблем.
но зачем тогда вообще тащить GWT
Причина одна, но для кого-то может быть крайне весомой — возможность писать клиентский код на Java.
Клиент-сайд состоит из двух частей: фреймворка и библиотеки виджетов. В качестве фреймворка довольно давно использую GWT + GQuery + RestyGWT. Доволен. Из печалек: медленная компиляция и неудобный дебаг в superdevmode. В качестве библиотеки виджетов можно использовать GWTBootstrap, GWT-Material, gwt-polymer-elements, любую CSS-based библиотеку, или даже интегрировать практически любой bullshit.js.
Про упомянутый Vaadin: да, подтормаживает (постоянная синхронизация состояния виджетов с сервером), спорно годится для интернет-проектов, но для энтерпрайзных админок и дэшбоардов — самое то. При помощи GWT можно использовать весь widgetset Vaadin-a на клиентской стороне без использования серверной части, что значительно разгоняет UI. Кроме того, есть полностью js-ный Vaadin Elements. Из печалек: из пресловутый Vaading Grid тормозит гораздо больше на клиенте, чем на сервере.
P.S. Хочу попробовать подергать Kotlin.js. Кстати, если уж о котлине заговорили, то вот фреймворк со схожим функционалом: https://github.com/Kotlin/ktor
GWT актуален ещё
Зачем вам этот тормозной монстр? Имхо проще отдельного фронтэндера иметь, чем работать с GWT...
Пользуясь случаем, попиарю свой проект: http://teavm.org/
Поддерживаются Java, Scala, Kotlin, есть Angular-образный фреймворк в комплекте
1. Не надо писать на джаваскрипте
2. Можно делать гуй на высоком уровне — есть готовые компоненты
- В TeaVM не надо писать на JavaScript, для того он и создан
- Есть возможность делать гуй на шаблонах (с биндингом, перерисовкой только изменившегося DOM). Пишите шаблоны под bootstrap — будут и компоненты. Можно создавать свои компоненты для шаблонизатора, можно биндиться к JavaScript-компонентам (как и в GWT). Но, разумеется, т.к. мой проект пока не нашёл широкого применения, под него есть только небольшой набор стандартных компонентов.
Я думал, Вы забросили этот проект. Ан-нет, уже даже достаточно юзабельная версия! На выходных попробую. Из пожеланий: добавить автоматический генератор врапперов к JS-библиотекам из TypeScript на DefinetlyTyped.
Мне всегда было интересно, как создатели таких проектов предполагают жить без reverse URL resolution.
reverse URL resolution.А не могли бы вы рассказать, что это за зверь такой?
ps: за 5+ лет еще не приходилось сталкиваться с этим термином; может эта фича не столь и нужная?
Но для того, чтобы она работала, нужно чтобы фреймворк на себя брал очень много обязанностей, как минимум фреймворку нужно, чтобы он знал все его роуты по именам; а чтобы это все корректно работало, то еще и по параметрам (PathParams, QueryParams, etc), т.е. сам фреймворк уже становится раздутым и сложным.
Часто в этом даже нету необходимости: роуты практически никогда не меняются после релиза. А если меняются, то на старый вешается редирект, чтобы не сломать ничего.
Это без сомнения крутая фича, но в микрофреймворке она избыточна. Если нужно этот функционал можно прикрутить через стороннюю библиотеку.
Искал JVM замену рельсам.
Rails-alike фреймворки существуют, но почему то они не переняли некоторых удобных деталей.
Эти самые URL, миграции, routes.rb с resources :foo, only: [:index, :show], лейауты. Разве что грусть-тоска по asset pipeline отпадает сама собой с появлением webpack и подобных.
jruby on rails сначала показались находкой. Но jruby быстро разочаровала страшными тормозами, очень сильная деградация в зависимости от количества библиотек/кода. TDD-ить невозможно. Прелоадеры глючат. Боль короче)
Нельзя взять и объявить resources :users скажем (такая фича есть разве что в grails, но до лаконичности рельсовой версии ей далеко).
Зачем это нужно? Проще менять роуты.
Database Evolutions не предоставляет никакого обобщенного DSL, нужно писать сырой SQL.
Да, контроля больше. Но с другой стороны, в 95% случаях мне хватало и рельсового DSL, а если уж не хватает, ничего не мешает (почти — автоотката все же не будет) написать специфичный сырой SQL.
Не покидает ощущение недоделанности. При всех недостатках рельсов, у них есть основная идея — удобство разработчика (да, я понимаю, зачастую в ущерб каким-то другим вещам). И вот эту идею в JVM-фреймворках реализуют, на мой взгляд, не в полной мере.
P.S. я разрабатываю и на RoR и на Java, т считаю, что RoR в JVM можно назвать лишь ее же но на jruby. Однако мне она не подошла — см. коммент выше.
Я так и не нашел какого-то единого устоявшегося термина, но да, это возможность сгенерировать ссылку, исходя из обработчика или идентификатора роута и параметров.
Пример из рельсов несколько чересчур магический и высокоуровневый, но суть верно передает.
Я понимаю, что это сильно за пределами вводной статьи, но это какой-то очень уж сферический пример. Поэтому у меня вопросы:
- как это все работает, когда тело метода
handle()
требует асинхронных операций. В базу, например сходить. И, поскольку Java многопоточная, то как обстоят дела с конкурентным доступом к одному и тому же request/response из разных потоков. - как использовать композицию? Например, накрутить кастомную авторизацию, чтобы сбегать в базу и найти пользователя по сессии.
Хотел бы затронуть такую тему как шаблонизаторы. Спарк имеет большую нативную поддержку оныхА Rocker поддерживается?
github.com/fizzed/rocker
1. Можно ли обойтись без Guava?
2. В чем необходимость использования «хэш-функция Murmur3»?
3. Можно ли Guava заменить на коллекцию из cuncerrent?
Спасибо за овтеты.
Жаль, что не на волне хайпа спрашиваю, и, вполне вероятно, мой вопрос никто не заметит.
Но как привязать конкретное доменном имя сайта к проекту на SparkJava?
Понятное дело, что через A запись мы можем указать IP:Port, но не указывать же IP:4567. Ведь есть еще HTTPS со своим 443 портом.
А если на сервере 2 сайта, то еще запутаннее становится.
Если для вас решение этой проблемы кажется очевидным, то очень прошу поделиться решением, т.к. у меня в голове пока каша из мелких кусочков.
Спасибо!
Как и с любым другим приложением: запускаете приложение на нужном порту, ставите перед ним reverse proxy (я предпочитаю nginx), который слушает 80 и 443 порты, выбирает нужный upstream на основе server_name
и выполняет tls offloading, чтобы приложению не нужно было заморачиваться с tls/ssl.
Получается, что раньше вы использовали Apache HTTP Server в качестве reverse proxy для ваших приложений на php/python/whatever. Никто не мешает использовать его в этой роли, если вы ближе знакомы с его конфигами. Если у вас нагрузка маленькая (а это с вероятностью в 4 девятки так), то это не принципиально. Если захотите экономить память, то имеет смысл пощупать nginx.
Также рекомендую при запуске java-приложений явно указывать -Xmx
и -Xms
, чтобы ограничить потребляемую память (например, -Xmx512m
ограничит верхнюю границу 512 MiB памяти в куче).
Про флаги виртуальномй машины для ограничения размером кучи уже в курсе. Уже использовал и Xms, Xmx и даже Xss. Спасибо.
Proxy pass на порт, где у вас запущено java приложение и все. От используемого фреймворка это никак не зависит
Только скорее в http модуле, а не в stream: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
port(80);
Вот ваше решение без всяких костылей.
Для занятия портов меньше 1024 нужны привелегии суперпользователя.
А запускать Java-процесс с такими правами — опасная затея.
Несколько vhost'ов вы будете в одном приложении разводить, писать свой reverse proxy и так далее? Зачем, если есть готовые человеческие решения?
Spark — Потрясающий веб-микрофреймворк для Java