Информациони системи 1/ЈПА и РЕСТ

Извор: SI Wiki
Пређи на навигацију Пређи на претрагу

На другој лабораторијској вежби ради се JPA (Java Persistence API) и REST (Representational State Transfer).

Поставка

Следећи поступак би требало да вас доведе до успешне поставке како бисте били спремни за покретање неког REST пројекта са странице предмета. Инструкције за прву лабораторијску вежбу су и даље потребне.

  1. Инсталирајте MySQL Workbench. Алтернативно, покретање било каквог MySQL (или MariaDB) сервера на рачунару ће радити. На пример, можете инсталирати XAMPP, покренути MySQL сервер на њему и користити phpMyAdmin као интерфејс.
    • При инсталацији MySQL Workbench, изаберите Developer Default опцију, од које ће вам релевантне компоненте бити MySQL Server и MySQL Workbench, па уколико инсталација пријави да се нека друга компонента не може инсталирати можете је прескочити.
    • Обавезно поставите лозинку за root корисника при инсталацији. Уколико је заборавите, можете покушати да је поново поставите помоћу овог упутства. Уколико ни то не ради, најбоље инсталирајте MySQL Server изнова.
    • Да бисте покренули MySQL сервер на Windows оперативном систему, можете отворити Command Prompt као администратор и покренути следеће команде:
      cd "C:\Program Files\MySQL\MySQL Server 8.0\bin"
      mysqld --install
      mysqld --initialize
      
      затим потражити Services опцију у Старт менију, и укључити сервис са префиксом MySQL.
    • Стефан Тубић је на вежбама мењао my.ini фајл како би подесио подразумевани storage engine на InnoDB. Ово није потребно, јер је након нове инсталације storage engine већ постављен на InnoDB.
  2. Преузмите Connector/J. Када вас пита за верзију, изаберите Platform Independent, и требало би да добијете један JAR фајл. Након тога, тај фајл можете убацити у директоријум са вашом инсталацијом GlassFish сервера, у директоријум glassfish/lib.
  3. Покрените NetBeans и GlassFish сервер. Уколико је био покренут пре него што сте убацили Connector/J, зауставите га и поново покрените.
  4. Направите нови JDBC Connection Pool. Параметри су следећи:
    • Resource Type: javax.sql.DataSource
    • Database Driver Vendor: MySql
      • Уколико сте на GlassFish 5.0 и пређете преко текстуалног поља након Database Driver Vendor, вредност ће бити избрисана.
    • Datasource Classname: com.mysql.cj.jdbc.MysqlDataSource
    • У додатним својствима конекције подесити:
      • password: Лозинка вашег MySQL корисника, не сме да буде празна и можете је променити из MySQL WorkbenchAdmnistrationUsers And Privileges (или користећи ALTER USER)
      • databaseName: Назив ваше MySQL базе
      • serverName: localhost
      • user: Назив вашег MySQL корисника, подразумевано постоји корисник са називом root.
      • portNumber: Подразумевано 3306, али понекад MySQL Workbench може да постави на 3308.
  5. Тестирати Connection Pool користећи Ping дугме.
    • Уколико добијате грешку у вези са com.mysql.cj.jdbc.MysqlDataSource или неким keystore фајлом (Keystore was tampered with...), пробајте да преко дугмета Add Property у Additional Properties табу додате својство useSSL са вредношћу false.
      • Уколико након овога добијате грешку у вези са public key retrieval, додајте својство allowPublicKeyRetrieval и поставите га на true.
    • Уколико и након корака изнад добијате грешку у вези са драјверском класом, проверите да ли сте на добро место убацили JAR фајл од Connector/J. Уколико имате више GlassFish сервера на рачунару, проверите да ли сте у добар сервер убацили. Пробајте да поред glassfish/lib убаците JAR фајл и у glassfish/bin и domains/domain1/lib.
    • Уколико као грешка изађе "Communications link failure", проверите да ли вам је укључен MySQL сервер, односно да ли можете да се на њега повежете из неког другог програма, попут MySQL Workbench. Такође проверите да ли гађате добар порт, пошто је подразумевани порт 3306, а не 3308 како је показано на вежбама.
    • Уколико у било ком тренутку поставке GlassFish сервер избаци грешку у вези са getOutputStream(), само покушајте поново.
  6. Направити JDBC Resource са новонаправљеним Connection Pool као конекцијом.
  7. Унутар NetBeans у ServicesDatabases кликните десним кликом на Drivers и изаберите New Driver.
  8. Код Driver File(s) изаберите Add и онда изаберите Connector/J JAR фајл који сте убацили у glassfish/lib директоријум, па додајте драјвер.
  9. Требало би да вам постане доступна опција Register MySQL server при десном клику на ServicesDatabases. Када то изаберете, можете додати параметре вашег MySQL сервера сличне онима које сте додавали за JDBC Connection Pool.
    • Овај корак вам омогућава да изаберете ову конекцију када радите NewEntity Classes from Database.
  10. У вашем persistence.xml фајлу, у Source табу, сада можете заменити садржај <jta-data-source> тага са називом вашег JDBC ресурса.
  11. Као додатан алат за тестирање ваше REST апликације можете преузети Postman.

Уколико покрећете нови REST пројекат, изаберите Java with MavenWeb Application. Обавезно гледајте GlassFish Server таб како бисте уочили грешке које се јављају током извршавања.

Напомене

  • Уколико сте направили нови празан пројекат и он не може да вам се покрене због грешке попут "Unable to load the mojo 'war' in the plugin 'org.apache.maven.plugins:maven-war-plugin:2.3' due to an API incompatibility", могуће је да имате више верзија JDK (Java Development Kit) инсталираних на рачунару, и да подразумевани JDK није подешен на 1.8. Покушајте да обришете остале JDK са рачунара, и да поставите подразумевани на 1.8. Подразумевани JDK може да се мења додавањем путање до JDK 1.8 у netbeans_jdkhome опцију у netbeans.conf фајл, или једноставно реинсталацијом NetBeans.
  • Уколико вам се деси HTTP грешка 404 (Not Found):
    • Прво проверите да ли сте добро уписали путању endpoint-а. Endpoint-ови су генерално на путањи localhost:8080/ProjectName/ApplicationPath/ResourcePath/EndpointPath, где:
      • ProjectName је име вашег пројекта, на пример restapi,
      • ApplicationPath је одређено анотацијом @ApplicationPath изнад главне класе вашег пројекта, односно класе изведене из Application (подразумевано постављено на resources),
      • ResourcePath је одређено анотацијом @Path изнад класе ресурса којем приступа, на пример popravke, и
      • EndpointPath је одређено анотацијом @Path изнад методе за тај endpoint.
    • Уколико је endpoint сигурно добар, могуће је да је апликација undeploy-ована због неке грешке у тренутном пројекту или некој од претходних итерација. Можете покушати да рестартујете GlassFish сервер и пратити сервер лог (GlassFish Server таб у Output прозору) да видите уколико се појављује нека грешка.
  • Уколико вам се дешава HTTP грешка 500 (Internal Server Error), требало би да део грешке видите на страници, али целу грешку можете пронаћи у сервер логу.
  • Уколико вам се у endpoint методи нађе аргумент без анотације поред себе, такав аргумент се шаље кроз тело (body) захтева, и у Postman треба поставити body на raw опцију. На пример, String аргумент се шаље са типом садржаја text/plain (Text опција у Postman), док се тип садржаја неке друге класе шаље као XML репрезентација те класе са типом садржаја application/xml (XML опција у Postman).
  • Уколико добијате TransactionRequiredException грешку при слању упита на неки endpoint, проверите да ли сте ставили @Stateless анотацију изнад класе ресурса.
  • Уколико добијате HTTP 405 (Method Not Allowed) грешку, то вероватно значи да шаљете GET захтеве на endpoint који прима захтеве само преко других метода.
  • Стефан Тубић на вежбама за MySQL сервер користи порт 3308. Стандардни и подразумевани порт за MySQL је 3306, тако да би требало да тај порт користите осим ако га нисте мењали.
    • Ако имате више од једног MySQL сервера на рачунару, можда буде потребно да једном промените порт. Могуће је да је због овога Стефану Тубићу порт био промењен на 3308.
  • Стефан Тубић је пред крај једних вежби направио грешку када је писао persistence.xml фајл и написао <jta-data-resource> уместо <jta-data-source>, па је на следећем снимку учитао готов пројекат и грешку приписао погрешној верзији Јаве. Ово вам може правити проблем уколико вам се јавља грешка како табела Kamion не постоји. Такође, у истом том persistence.xml фајлу је писало transactionType уместо transaction-type, што вам исто може правити проблем.
  • У готовом пројекту за компанију за превозе (kzp, пројекат restapi) у Mehanicari.java фајлу налази се @PersistenceContext(unitName = "my_persistence_unit"), иако се јединица перзистенције зове Zad3PU. То може проузроковати неке грешке, барем у овом ресурсу.
  • Уколико вам се приликом враћања одговора са сервера деси StackOverflowException, вероватно вам се десила бесконачна рекурзија при серијализацији објекта због недостатка @XmlTransient анотације која спречава серијализацију неког поља. То се обично дешава када класа A има поље типа B или List<B>, а класа B поље типа A или List<A>, па серијализатор ради следеће:
    1. креће са серијализацијом објекта класе A,
    2. нађе његово поље типа B и види да нема анотацију @XmlTransient,
    3. креће са серијализацијом објекта класе B,
    4. нађе његово поље типа A и види да нема анотацију @XmlTransient,
    5. поново креће са серијализацијом истог објекта класе A и тако у круг...
    • Пример овога може да буде са вежби са компанијом за превоз, где, уколико ентитет Zaposlen не би имао @XmlTransient анотацију изнад getMehanicar() или getVozac() методе, дешавала би се бесконачна серијализација тих ентитета.
  • За пројекат може да вам се деси грешка која пријављује да ентитетске класе можда нису означене са @Entity. То се обично дешава у случају да вам је transaction-type постављен на RESOURCE_LOCAL али немате све класе излистане у persistence.xml.