• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

podstawy springa - serwlety, serwery aplikacji, web.xml

Object Storage Arubacloud
0 głosów
671 wizyt
pytanie zadane 25 września 2018 w Java przez must Bywalec (2,980 p.)

Hej. Przekopałem już wiele stron nt. aplikacji webowych i chciałbym zweryfikować swoją wiedzę na ten temat oraz nt. Springa.

Serwer aplikacji jest tak jakby naszym komputerem, ale w internecie. (np. Tomcat) Potrzebny jest on do uruchomienia aplikacji. Wysyła on żądanie do klasy, która tak jakby jest zdolna do przetwarzania tych żadań, czyli serwleta. Servlety konfigurujemy w web.xml. Dobrze myślę?

I teraz nie wiem, na niektórych stronach piszą, że serwer aplikacji = kontener webowy. Czy jest to prawdą? Czy właśnie Tomcat to jest taki serwer, tylko tak jakby z węższymi ale prostszymi możliwościami?

Korzystając z ksiązki "Spring MVC. Przewodnik dla początkujących" tworzymy tam również Defaultservlet-servlet.xml, gdzie mam taki kod:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:mvc="http://www.springframework.org/schema/mvc"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-4.0.xsd
 http://www.springframework.org/schema/mvc
 http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
 <mvc:annotation-driven />
 <context:component-scan base-package="com.packt.webstore" />
 <bean class="org.springframework.web.servlet.view.
 InternalResourceViewResolver">
 <property name="prefix" value="/WEB-INF/jsp/" />
 <property name="suffix" value=".jsp" />
 </bean

I tutaj mam pytanie. Dlaczego potrzebuje taki plik? Chodzi mi o to, że wytłumaczyli po co jest to:

<mvc:annotation-driven />
 <context:component-scan base-package="com.packt.webstore" />
 <bean class="org.springframework.web.servlet.view.
 InternalResourceViewResolver">
 <property name="prefix" value="/WEB-INF/jsp/" />
 <property name="suffix" value=".jsp" />

, że potrzebne jest to do wyszukania klas kontrolerów, widoków. ale na różnych stronach ludzie tworza swoje serwlety z metodami doPost, doGet etc. nie posiadają takiego pliku i wszystko działa. Np. tutaj: https://javastart.pl/baza-wiedzy/darmowy-tutorial-jee/jee/pierwszy-servlet-hello-world

1 odpowiedź

+2 głosów
odpowiedź 25 września 2018 przez mbabane Szeryf (79,280 p.)
edycja 25 września 2018 przez mbabane
 
Najlepsza
Mieszasz dwa szczegóły Java EE to osobny byt, który docelowo służy do aplikacji webowych. Natomiast Spring, a konkretnie Spring-WEB-MVC jest niezależnym frameworkiem, który służy do tego samego co Java EE ale nie jest tym samym - pod spodem Springa mvc jest Java EE.

Według mnie obczaj sobie najpierw o co chodzi w Javie EE, a dopiero po tym przejdź do Springa. Tylko nie od razu do Spring MVC tylko od zwykłego Springa do wstrzykiwania zależności - bo jak to ominiesz to możesz potem mieć problemy ze zrozumieniem pewnych elementów, w dalszych Springowych pod-projektach.

Zobacz sobie ile Spring ma pod-projektów:

https://spring.io/docs/reference

Springa zacznij sobie od tego:

https://docs.spring.io/spring/docs/5.1.0.RELEASE/spring-framework-reference/

 

To co opisujesz w ostatnim akapicie dotyczy Java EE, a konkretniej servletów. Dowiedz się czym jest servlet, jak się go używa itd. ale nie ucz się pisać w nim aplikacji, ponieważ tak się nie robi. Kod napisany servletem jest bardzo trudny w utrzymaniu.

 

I jeszcze jedna rzecz. Aktualnie w nowym kodzie odchodzi się od ustawień w plikach xml. Wszelkie konfiguracje robi się przy użyciu adnotacji Java - w springu też.
2
komentarz 25 września 2018 przez mbabane Szeryf (79,280 p.)
edycja 25 września 2018 przez mbabane

Odnosząc się jeszcze do tego:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:mvc="http://www.springframework.org/schema/mvc"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-4.0.xsd
 http://www.springframework.org/schema/mvc
 http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
 <mvc:annotation-driven />
 	<context:component-scan base-package="com.packt.webstore" />
 	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
 	<property name="prefix" value="/WEB-INF/jsp/" />
 	<property name="suffix" value=".jsp" />
 </bean>
</beans>

Jest to definicja konfiguracji wykorzystywana w springu MVC do mapowania zwracanych przez kontroler nazw w postaci stringów na widoki zapisane w katalogu /WEB-INF-/jsp/ i kończących się na .jsp. Właściwie to jest to zwyczajna definicja ziarna springowego - dlatego wspomniałem wyżej aby najpierw przerobić zagadnienia związane ze "zwykłym" springiem. Czyli jeśli metoda kontrolera wygląda tak:

@GetMapping("/")
public String home()
{
    return "home";
}

To InternalResourceViewResolver zmieni  home na widok home.jsp zapisany w /WEB-INF/jsp/. Gdyby nie było zdefiniowanego ViewResolver-a, wówczas trzeba by ścieżkę podawać ręcznie:

@GetMapping("/")
public String home()
{
    return "/WEB-INF/jsp/home.jsp";
}

Prócz wygody dla programisty daje to jeszcze tyle, że do /WEB-INF nie ma się dostępu z zewnątrz aplikacji - tylko kontrolery mają tam dostęp - a więc jest to pewien element zabezpieczający bo w widoku .jsp (czy innym) mogą być zawarte elementy, które nie mogą być ujawniane.

Po więcej szczegółów trzeba zajrzeć do dokumentacji:

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/view/InternalResourceViewResolver.html

 

Jeśli chodzi o te linie:

<mvc:annotation-driven />
<context:component-scan base-package="com.packt.webstore" />

Pierwsza z nich powoduje, że Spring sam konfiguruje sobie zależności potrzebne do działania Srping-MVC: Tutaj jest więcej szczegółów:
https://www.codelooru.com/2010/10/what-does-mvcannotation-driven-do.html

Natomiast druga linia oznacza, że w pakiecie com.packt.webstore i jego podpakietach ma szukać rzeczy należących do Springa, zdefinowanych w kodzie Javy. Mogą być to plik konfiguracyjne (adnotacja @Configuration) z ziarnami (beany), serwisy (adnotacja @Service), zwykłe komponenty (adnotacja @Component) czy kontrolery Springa mvc (adnotacja @Controller).

Aktualnie wszystko to robi się w Javie bez użycia XML.

komentarz 25 września 2018 przez must Bywalec (2,980 p.)

@mbabane, to co napisałeś w komentarzu, to jest właśnie wszystko opisane w książce, nie o to mi chodziło. Bardziej zależało mi na tym, aby dowiedzieć się, dlaczego w tym linku autor nie robi xml'a tego typu, skoro własnie spring mvc jest (jeżeli tak mogę to nazwać) pochodną javy ee.

Właśnie napisałem w pytaniu co to jest serwlet i chciałem zweryfikować czy dobrze to rozumiem (a także inne elementy wchodzące w skład aplikacji webowych) :

Serwer aplikacji jest tak jakby naszym komputerem, ale w internecie. (np. Tomcat) Potrzebny jest on do uruchomienia aplikacji. Wysyła on żądanie do klasy, która tak jakby jest zdolna do przetwarzania tych żadań, czyli serwleta. Servlety konfigurujemy w web.xml. Dobrze myślę?

I teraz nie wiem, na niektórych stronach piszą, że serwer aplikacji = kontener webowy. Czy jest to prawdą? Czy właśnie Tomcat to jest taki serwer, tylko tak jakby z węższymi ale prostszymi możliwościami?

komentarz 25 września 2018 przez mbabane Szeryf (79,280 p.)
edycja 25 września 2018 przez mbabane

Ponieważ spring to wszystko przykrywa i w pewnym stopniu załatwia za nas. Spring MVC działa na bazie servletów i z Javy ee ma w zasadzie chyba tylko tyle. Tak w web.xml definiuje się servlety i ustawienia aplikacji Javy EE. Jeśli chodzi o springa mvc to należy zdefiniować tylko DispatcherServlet, który robi całą robotę z delegowaniem żądań do odpowiednich klas javy - nazywanych kontrolerami. Wszystkie żądania lecą do tego DispatcherServlet. Można go ustawić za pomocą XML w web.xml tak:

<web-app>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/app-context.xml</param-value>
    </context-param>

    <servlet>
        <servlet-name>app</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>app</servlet-name>
        <url-pattern>/app/*</url-pattern>
    </servlet-mapping>

</web-app>

jednak jak wspomniałem odchodzi się od xml i wszystko robi się w Javie powyższe w Springu robi się tak:

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletCxt) {

        // Load Spring web application configuration
        AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
        ac.register(AppConfig.class);
        ac.refresh();

        // Create and register the DispatcherServlet
        DispatcherServlet servlet = new DispatcherServlet(ac);
        ServletRegistration.Dynamic registration = servletCxt.addServlet("app", servlet);
        registration.setLoadOnStartup(1);
        registration.addMapping("/app/*");
    }
}

Ale Spring-mvc jeszcze bardziej to uprościł i aktualnie robi się to tak:

public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] { RootConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] { App1Config.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/app1/*" };
    }
}

Kontener servletów szuka w aplikacji klasy implementującej javax.servlet.ServletContainerInitializer, W springu zrobili z tego interfejs WebApplicationInitializer, a ten interfejs implementowany jest przez AbstractAnnotation (długa nazwa zerknij na listing). Dzięki temu nie trzeba bawić się w XML.

Z książek o Springu, które mogę polecić to chyba tylko Spring w akcji wydanie IV.

Po więcej szczegółów odsyłam tutaj: https://docs.spring.io/spring/docs/5.1.0.RELEASE/spring-framework-reference/web.html#spring-web

komentarz 25 września 2018 przez must Bywalec (2,980 p.)

A co jeżeli o to chodzi? Dobrze rozumeim co to jest serwlet, serwrer aplikacji  kontener webowy?

Serwer aplikacji jest tak jakby naszym komputerem, ale w internecie. (np. Tomcat) Potrzebny jest on do uruchomienia aplikacji. Wysyła on żądanie do klasy, która tak jakby jest zdolna do przetwarzania tych żadań, czyli serwleta. Servlety konfigurujemy w web.xml. Dobrze myślę?

I teraz nie wiem, na niektórych stronach piszą, że serwer aplikacji = kontener webowy. Czy jest to prawdą? Czy właśnie Tomcat to jest taki serwer, tylko tak jakby z węższymi ale prostszymi możliwościami?

komentarz 25 września 2018 przez mbabane Szeryf (79,280 p.)
edycja 25 września 2018 przez mbabane

Jeśli chodzi o Apache Tomcat to na stronie głownej jest coś takiego:

The Apache Tomcat® software is an open source implementation of the Java Servlet, JavaServer Pages, Java Expression Language and Java WebSocket technologies

http://tomcat.apache.org

Tomact obsługuje Javaowe aplikacje webowe stąd nazywa się go kontenerem servletów. Co to jest kontener servletów tutaj wyjaśnia specka Java Servlet API:

The servlet container is a part of a Web server or application server that provides the network services over which requests and responses are sent, decodes MIME-based requests, and formats MIME-based responses. A servlet container also contains and manages servlets through their lifecycle.

A servlet container can be built into a host Web server, or installed as an add-on component to a Web Server via that server’s native extension API. Servlet containers can also be built into or possibly installed into Web-enabled application servers. 

All servlet containers must support HTTP as a protocol for requests and responses...

A sam servlet w tej specyfikacji wyjaśniony jest tak:

A servlet is a Java™ technology-based Web component, managed by a container, that generates dynamic content. 

Link do tej specki:

http://download.oracle.com/otn-pub/jcp/servlet-4-final-eval-spec/servlet-4_0_FINAL.pdf

W powyżej spece wyjaśnione jest (na stornie 22) jak mniej więcej działa servlet, więc porównaj sobie swój tok rozumowania z tym co jest tam zawarte - wydaje się że masz dobry tok rozumowania (z grubsza).

Jeśli chodzi o ten serwer aplikacji to może mieć to dwojakie znaczenie. Jedno to część aplikacji wchodząca w architekturę klient-serwer, która zwykle przetwarza dane odbierane przez klienta. I to może być zwyczajna aplikacja napisana np. w Javie, bez użycia servletów, ale komunikująca się przez sieć (np. z wykorzystaniem gniazd sieciowych). 

Drugie znaczenie bardziej ogólne to własnie będzie m.in. Apache Tomcat - jest on serwerem, do którego łączą się klienci np. za pomocą przeglądarki - czyli ten kontener webowy. Web to sieć, klienci łączą się przez sieć zwykle za pomocą HTTP - stąd zdaje się kontener webowy - może on przechowywać więcej niż jedną aplikację. Apache Tomcat można wykorzystać własnie jako taki kontener webowy do budowy aplikacji webowych z wykorzystaniem Java. To kontener wzięło się chyba własnie z tego pojęcia Kontener Servletów.

Teraz jeszcze o co mi chodziło z tym doczytaniem o servlecie. Chodziło mi bardziej z punktu widzenia programisty, jak to zakodować żeby z tego servletu skorzystać i co się z tym wiąże. Te zagadnienia poruszone są tutaj:

https://docs.oracle.com/javaee/7/tutorial/servlets.htm#BNAFD

komentarz 25 września 2018 przez must Bywalec (2,980 p.)
Skąd jest to słowo kontener. Mam na myśli ile tych serwletów może tam być, bo skoro serwlet to klasa obsługującą żądania HTTP, a zawiera ona wszystkie żądania (wszystkie metody doGet,doPost...) to dlaczego jest to w liczbie mnogiej?
komentarz 25 września 2018 przez mbabane Szeryf (79,280 p.)

Każdemu serwletowi przypisuje się URL więc możesz ich mieć więcej niż jeden w jednej aplikacji:

@WebServlet("/myServletOne")
public class MyServletOne extends HttpServlet
{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    {
        PrintWriter writer = resp.getWriter();
        writer.write("MyServletOne");
    }
}

@WebServlet("/myServletTwo")
public class MyServletTwo extends HttpServlet
{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    {
        resp.getWriter().write("MyServletTwo");
    }
}

I teraz masz dwa servlety dostępne pod rożnymi adresami:

.../myServletOne

.../myServletTwo

Dlatego zwróciłem uwagę na to abyś zapoznał się z programowaniem servletów.

Edytowałem jeden post, w którym opisałem konfiguracje Spring-mvc, bo wkradł się tam mały błąd. Teraz jest dobrze. Błąd polegał na tym, że napisałem po pierwsze, że WebApplicationInitializer to klasa (jest to interfejs). Mało tego napisałem, że rozszerza on javax.servlet.ServletContainerInitializer co też było błędem z mojej strony, bo w springu mvc ten interfejs nazwali własnie: WebApplicationInitializer:

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/WebApplicationInitializer.html

1
komentarz 25 września 2018 przez mbabane Szeryf (79,280 p.)

Jeszcze żeby była jasność bo napisałem:

bo w springu mvc ten interfejs nazwali własnie: WebApplicationInitializer:

To nie jest tak, że   javax.servlet.ServletContainerInitializer = WebApplicationInitializer. Ten drugi, springowy interfejs jest jakby odpowiednikiem tego oryginalnego. Oryginalny servletowy interfejs w springu implementowany jest przez SpringServletContainerInitializer:

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/SpringServletContainerInitializer.html

Podobne pytania

0 głosów
2 odpowiedzi 214 wizyt
pytanie zadane 13 września 2018 w Rozwój zawodowy, nauka, praca przez must Bywalec (2,980 p.)
0 głosów
0 odpowiedzi 162 wizyt
0 głosów
0 odpowiedzi 166 wizyt

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...