PSI. Ćwiczenia numer 9 0. Kilka przydatnych linków http://wiki
Transkrypt
PSI. Ćwiczenia numer 9 0. Kilka przydatnych linków http://wiki
PSI. Ćwiczenia numer 9 0. Kilka przydatnych linków http://wiki.eclipse.org/Jetty/ http://www.coreservlets.com/ http://mvnrepository.com/ 1. Pobieramy najpierw mavena ze strony http://maven.apache.org/ → Download W Netbeansie (którego będziemy wykorzystywać głównie jako edytor) ustawiamy ścieżkę do mavena (Tools->Options->Java). 2. Zakładamy nowy projekt maven o nazwie java1. Wybieramy typ java application. 3. Znajdujemy plik mvn.bat (w bin). Ustawiamy tam pierwszą linię set JAVA_HOME=C:\Program Files\Java\jdk1.6.0_21 (musimy sprawdzić, gdzie na dysku mamy jdk) Z kolei folder bin z mavena dodajemy do ścieżki (PATH). Testujemy przez wpisanie mvn z wiersza poleceń. 4. Teraz ustawiamy się w folderze projektu i robimy mvn clean install 5. W src/main tworzymy ręcznie (np. w NetBeans) katalog webapp a w nim podkatalog WEB-INF. Wszystko co umieścimy w webapp będzie udostępnione (ścieżka w webapp odpowiada ścieżce w url) poza katalogiem WEB-INF. 6. Proszę w webapp umieścić plik index.html a w nim następującą treść. <!DOCTYPE html> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <h1>Hello World Webapp</h1> <a href="/hello">Hello Servlet</a><br/> <a href="/hello2">Hello Servlet Annotations</a><br/> <a href="/jsptest.jsp">Test jsp</a><br/> </body> </html> 7. Do pliku konfiguracyjnego mavena pom.xml proszę dodać wpis <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <jettyVersion>8.1.8.v20121106</jettyVersion> </properties> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-server</artifactId> <version>${jettyVersion}</version> </dependency> <build> <plugins> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>${jettyVersion}</version> </plugin> </plugins> </build> 8. Robimy mvn jetty:run i sprawdzamy co jest na porcie 8080 (domyślnym). 9. Teraz do projektu dodamy stronę jsp. Proszę w webapp umieścić plik jsptest.jsp a w nim <%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <title>JSP Page</title> </head> <body> <% int x = 5; %> <h1> <%for(int i=0;i<10;i++) { %> <%=x%><br> <%}%> </h1> </body> </html> Proszę przetestować działanie strony jsp. Generalnie umieszczanie kodu java bezpośrednio w jsp nie jest zalecane bo taki kod jest trudny w debugowaniu i błędy wychodzą dopiero przy wykonaniu a nie przy kompilacji. Stąd użycie bibliotek znaczników. 10. Teraz dodamy serwlety. W Servlet API starszym od 3.0 wymagany był plik web.xml. Od 3.0 ten plik nie jest wymagany ale jest dozwolony. Serwlet to obiekt, który jest stworzony przez serwer (kontener serwletów) i wywoływany przez refleksję i wywołanie zwrotne, gdy przyjdzie żądanie http, które serwer uzna, że należy oddelegować do serwletu. Mapowanie ścieżki do instancji serwletu można skonfigurować przez wpis w pliku web.xml <servlet> <servlet-name>Hello</servlet-name> <servlet-class>com.mycompany.java1.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Hello</servlet-name> <url-pattern>/hello/*</url-pattern> </servlet-mapping> lub przez adnotację @WebServlet("/hello2") Wadą adnotacji jest to, że jest na stałe wkompilowana do kodu co wymaga zmiany w odpowiednim miejscu w kodzie i przekompilowania klasy gdy zmienimy ścieżkę. Z kolei wadą xml jest to, że musi być i jest dość rozwlekły. 11. Proszę stworzyć klasę serwletu public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); response.setStatus(HttpServletResponse.SC_OK); PrintWriter out = response.getWriter(); out.println("<h1>Hello Servlet</h1>"); out.println("session=" + request.getSession(true).getId()); } } i drugą taką samą ale z adnotacją jak w p. 10 (proszę zmienić napis Hello Servlet na Hello Servlet through Annotation). 12. Wewnątrz pluginu jetty (po version) można dodać <configuration> <scanIntervalSeconds>2</scanIntervalSeconds> </configuration> Niestety to działa tylko gdy zmieniamy zawartość webapp. Gdy zmieniamy klasy trzeba je przekompilować i zrestartować serwer. Proszę po dodaniu tego wpisu przetestować zmianę np. w index czy w jsp. 13. Do WEB-INF proszę wgrać plik jetty_my.xml (powinien być do ściągnięcia z mojej strony). W pom.xml proszę ustawić w <configuration> obok scanIntervalSeconds <jettyXml> ${basedir}/src/main/webapp/WEB-INF/jetty_my.xml </jettyXml> Proszę zrestartować serwer i przetestować. 14. Teraz w jetty_my.xml dodajemy wpis środowiskowy. Jest to stała zdefiniowana w serwerze. <New id="name" class="org.eclipse.jetty.plus.jndi.EnvEntry"> <Arg>name</Arg> <Arg type="java.lang.Integer">4000</Arg> <Arg type="boolean">true</Arg> </New> W serwlecie można go pobrać przez try { InitialContext ic = new InitialContext(); Integer mySpecialValue = (Integer) ic.lookup("java:comp/env/name"); response.getWriter().println("<br>" + mySpecialValue); } catch (NamingException ex) { Logger.getLogger(HelloServlet.class.getName()).log(Level.SEVERE, null, ex); } w takim podejściu serwlet sam sobie wyciąga zasób z usługi nazewniczej JNDI. Alternatywnie można go wstrzyknąć do klasy serwletu przez adnotację @Resource (name="name", type=Integer.class) private Integer number; out.println("<br>"+number); wówczas kontener wstawia do pola w klasie serwletu referencję do zasobu. Proszę przetestować oba podejścia. 15. Teraz proszę pobrać i rozpakować serwer mysql. http://www.mysql.com/downloads/mysql/ Najlepiej wersję 5.5.28 win32. Serwer startujemy przez mysqld (w bin). 16. Ustawiamy w NetBeans połączenie z serwerem (Services->Databases->New connection) Zakładamy bazę o nazwie resourcetest a w niej tabelę student z polami imię i nazwisko. Dodajemy kilka przykładowych rekordów. 17. W pom.xml ustawiamy zależności wewnątrz pluginu jetty <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.21</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> </dependencies> 18. W jetty_my.xml dodajemy wpis tworzący pulę połączeń i udostępniający ją jako zasób w JNDI <New id="DSTestPool" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg>jdbc/DSTestPool</Arg> <Arg> <New class="org.apache.commons.dbcp.BasicDataSource"> <Set name="driverClassName">com.mysql.jdbc.Driver</Set> <Set name="url">jdbc:mysql://localhost:3306/resourcetest</Set> <Set name="username">root</Set> <Set name="password"></Set> <Set name="maxActive">100</Set> <Set name="maxIdle">30</Set> <Set name="minIdle">10</Set> </New> </Arg> </New> 19. Teraz mamy dwie możliwości. Albo dodać wpis w web.xml albo dodać adnotację w serwlecie. W web.xml <resource-ref> <res-ref-name>jdbc/DSTestPool</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> Wówczas w kodzie java try { InitialContext ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/DSTestPool"); //* out.println("<br> DataSource obtained: " + ds); out.println("<br/>"); Connection c = ds.getConnection(); Statement s = c.createStatement(); ResultSet rs = s.executeQuery("SELECT * FROM student"); while (rs.next()) { out.print(rs.getString("imie")); out.print(" "); out.print(rs.getString("nazwisko")); out.println("<br/>"); } c.close(); } catch (Exception e) { out.println("Unsuccessful..."); out.println(e.getMessage()); e.printStackTrace(out); } Alternatywnie linijkę w kodzie oznaczoną przez * oraz wpis w webxml można zakomentować, natomiast w klasie serwletu można umieścić pole opatrzone adnotacją @Resource (name="jdbc/DSTestPool", type=DataSource.class) private DataSource ds; Proszę przetestować obie metody.