Archiwa kategorii: Zdaj OCEWCD

Zdaj OCEWCD – pytanie 11

Co będzie efektem uruchomienia poniższego kodu servletu?

@WebServlet("/Test")
public class TestServlet extends HttpServlet
{
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        request.getRequestDispatcher("test.jsp").forward(request, response);
    }
}
package eu.javablog.ocewcd;

public class BeanClass
{
    private String text;

    public BeanClass(String text)
    {
        this.text = text;
    }

    public String getText()
    {
        return text;
    }

    public void setText(String text)
    {
        this.text = text;
    }
}
<html>
<head>
    <title>Test Page</title>
</head>
<body>
    <jsp:useBean id="myBean" type="eu.javablog.ocewcd.BeanClass" scope="request">
        <jsp:setProperty name="myBean" property="text" value="DEFAULT" />
    </jsp:useBean>

    <p>${myBean.text}</p>
</body>
</html>

 

  1. Wyświetlony zostanie pusty ciąg znaków.
  2. W trakcie wykonania rzucony zostanie wyjątek.
  3. Kod nie skompiluje się.
  4. Wyświetlony zostanie DEFAULT.
  5. Wyświetlony zostanie null.

 

Pokaż odpowiedź »

Poprawna jest odpowiedź nr 2.

Podchwytliwość tego pytania polega na tym, że dla taga jsp:useBean podaliśmy wartość atrybutu type, a nie class. W takim wypadku, jeśli w podanym scope nie ma wskazanego przez nas atrybutu, bean nie będzie stworzony. Zamiast tego rzucony zostanie wyjątek: java.lang.InstantiationException: bean myBean not found within scope.

Zdaj OCEWCD – pytanie 10

Co się stanie po uruchomieniu kodu poniższego servletu?

@WebServlet("/Test")
public class TestServlet extends HttpServlet
{
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        request.setAttribute("myBean", new BeanClass("SERVLET"));
        request.getRequestDispatcher("test.jsp").forward(request, response);
    }
}
public class BeanClass
{
    private String text;

    public BeanClass(String text)
    {
        this.text = text;
    }

    public String getText()
    {
        return text;
    }

    public void setText(String text)
    {
        this.text = text;
    }
}
<html>
<head>
    <title>Test Page</title>
</head>
<body>
    <jsp:useBean id="myBean" class="eu.javablog.ocewcd.BeanClass">
        <jsp:setProperty name="myBean" property="text" value="DEFAULT" />
    </jsp:useBean>

    <p>${myBean.text}</p>
</body>
</html>

 

  1. Wydrukowany zostanie wyraz DEFAULT.
  2. Kod nie skompiluje się.
  3. Wydrukowany zostanie wyraz SERVLET.
  4. W trakcie działania rzucony zostanie wyjątek.
  5. Wyświetlony będzie pusty String.

 

Pokaż odpowiedź »

Poprawna jest odpowiedź nr 4.

Powodem rzucenia wyjątku jest fakt, iż tag jsp:useBean będzie próbował stworzyć nowy obiekt typu BeanClass. W tym celu wymaga on jednak bezargumentowego konstruktora, którego ta klasa nie posiada. Mylący w tym pytaniu jest także fakt dodania do obiektu żądania nowego atrybutu w kodzie servletu. Mogłoby się wydawać, że jsp:useBean wykorzysta go, i nie będzie próbował tworzyć nowej instancji. Tak się jednak nie dzieje, ponieważ domyślnym scope’em tego taga jest page scope. Nasz argument znajduje się natomiast w request scope. Do poprawy przykładu wystarczyłoby więc dodanie do naszego jsp:useBean atrybutu scope=”request”, bądź też uzupełnienie klasy BeanClass o bezargumentowy konstruktor.

Zdaj OCEWCD – pytanie 9

Co zostanie wydrukowane użytkownikowi po wykonaniu poniższego kodu, zakładając, że w żądaniu znajduje się ciastko o nazwie cname i wartości val?

@WebServlet("/Test")
public class TestServlet extends HttpServlet
{
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        Cookie cookie = request.getCookie("cname");
        response.getWriter().println(cookie.getValue());
    }
}

 

  1. Wydrukowane zostanie val.
  2. Nic nie będzie wydrukowane – zostanie rzucony wyjątek.
  3. Kod nie skompiluje się.
  4. Wydrukowane zostanie null.
  5. Wydrukowane zostanie cname.

 

Pokaż odpowiedź »

Poprawna jest odpowiedź nr 3.

Klasa HttpServletRequest nie posiada metody getCookie(). Możemy jedynie pobrać tablicę wszystkich ciastek obecnych w żądaniu. Znalezienie tego o interesującej nas nazwie należy zaimplementować samemu. Najprostsza metoda o takim działaniu wygląda następująco:

private Cookie getCookie(HttpServletRequest request, String name)
{
    for(Cookie c : request.getCookies())
    {
        if(c.getName().equals(name))
        {
            return c;
        }
    }

    return null;
}

Zdaj OCEWCD – pytanie 8

Co zostanie wydrukowane użytkownikowi po wykonaniu poniższego kodu servletu?
Należy założyć, że używamy Javy EE6.

@WebServlet("/Test")
public class TestServlet extends HttpServlet
{
    private static final String ATTR_NAME = "attr";

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        HttpSession session = request.getSession();
        session.setAttribute(ATTR_NAME, "val");

        session.setMaxInactiveInterval(0);

        Object obtained = session.getAttribute(ATTR_NAME);
        response.getWriter().println(obtained);
    }
}

 

  1. Wydrukowane zostanie ‚val’.
  2. Wydrukowane zostanie ‚null’.
  3. Kod nie skompiluje się.
  4. W trakcie wykonania rzucony zostanie wyjątek.
  5. Wydrukowane zostanie ‚attr’.

 

Pokaż odpowiedź »

Poprawna jest odpowiedź nr 1.

Linią komplikującą to pytanie jest z pewnością linia 11. Należy wiedzieć jakie znaczenie ma argument 0 w przypadku metody setMaxInactiveInterval. Jest to o tyle podchwytliwe, że w Javie EE5 cyfra 0 oznaczała natychmiastowe unieważnienie sesji. W przypadku powyższego kodu podczas pobierania atrybutu rzucony zostałby wyjątek IllegalStateException. Pytanie odnosi się jednak do Javy EE6, gdzie podobnie jak liczby ujemne, zero oznacza nieograniczony czas ważności sesji.

Zdaj OCEWCD – pytanie 7

Co zostanie wyświetlone użytkownikowi po wywołaniu servletu w następujący sposób?
http://host:port/context/Test?param=old

Należy założyć, że w miejsce host, port i context wstawione są poprawne wartości.

@WebServlet("/Test")
public class TestServlet extends HttpServlet
{
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        RequestDispatcher dispatcher = request.getRequestDispatcher("/Target?param=new");
        dispatcher.forward(request, response);
    }
}
@WebServlet("/Target")
public class TargetServlet extends HttpServlet
{
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        String first = request.getQueryString();
        String second = (String) request.getAttribute("javax.servlet.forward.query_string");

        response.getWriter().println(first + " " + second);
    }
}

 

  1. param=new null
  2. param=new param=old
  3. Kod nie skompiluje się.
  4. param=old param=old
  5. param=old null

 

Pokaż odpowiedź »

Poprawna jest odpowiedź nr 2.

W sytuacji, kiedy jeden servlet wywołuje drugi korzystając z metody forward w klasie RequestDispatcher, obiekt HttpServletRequest w docelowym servlecie zawiera już zaktualizowany query string - wartość przekazaną przy okazji wywołania metody getRequestDispatcher(). Jest jednak możliwość dostania się do oryginału – wystarczy odczytać wartość atrybutu żądania o nazwie javax.servlet.forward.query_string. Istnieją również analogiczne atrybuty dla innych kluczowych wartości przechowywanych w obiekcie żądania:

  • javax.servlet.forward.request_uri 
  • javax.servlet.forward.context_path 
  • javax.servlet.forward.servlet_path 
  • javax.servlet.forward.path_info
Odpowiadają kolejno rezultatom wywołania metod getRequestURI, getContextPath, getServletPath, oraz getPathInfo klasy HttpServletRequest.

Zdaj OCEWCD – pytanie 6

Co zostanie wydrukowane po starcie aplikacji zawierającej poniższy deskryptor wdrożenia oraz klasy?

<web-app ...>
    <listener>
        <listener-class>
            eu.javablog.ocewcd.SecondContextListener
  	</listener-class>
    </listener>
    <listener>
        <listener-class>
            eu.javablog.ocewcd.FirstContextListener
        </listener-class>
    </listener>
</web-app>
public class FirstContextListener implements ServletContextListener
{
    @Override
    public void contextDestroyed(ServletContextEvent arg0)
    {

    }

    @Override
    public void contextInitialized(ServletContextEvent arg0)
    {
        System.out.println("FIRST");
    }
}
public class SecondContextListener implements ServletContextListener
{
    @Override
    public void contextDestroyed(ServletContextEvent arg0)
    {

    }

    @Override
    public void contextInitialized(ServletContextEvent arg0)
    {
        System.out.println("SECOND");
    }
}

 

  1. Nic nie zostanie wydrukowane.
  2. Wydrukowane zostanie odpowiednio FIRST i SECOND.
  3. Kolejność wydruku zależy od implementacji kontenera.
  4. Wydrukowane zostanie odpowiednio SECOND i FIRST.
  5. Kod nie skompiluje się.

 

Pokaż odpowiedź »

Poprawna jest odpowiedź nr 4.

Kolejność wykonania listenerów jest zgodna z kolejnością ich deklaracji w deskryptorze wdrożenia. Jest to zachowanie gwarantowane, opisane w specyfikacji.

Zdaj OCEWCD – pytanie 5

Co zostanie wydrukowane po skompilowaniu i uruchomieniu poniższego servletu?

@WebListener
public class RequestAttributeListener implements ServletRequestAttributeListener
{
    @Override
    public void attributeAdded(ServletRequestAttributeEvent e)
    {
        System.out.println("ADDED:" + e.getValue());
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent e)
    {
        System.out.println("REMOVED:" + e.getValue());
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent e)
    {
        System.out.println("REPLACED:" + e.getValue());
    }
}
@WebServlet("/Test")
public class TestServlet extends HttpServlet
{
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        request.setAttribute("attr", "1");
        request.setAttribute("attr", "2");
        request.removeAttribute("attr");
    }
}

 

  1. ADDED:1 REPLACED:2 REMOVED:null
  2. ADDED:1 REPLACED:1 REMOVED:null
  3. ADDED:1 REPLACED:2 REMOVED:
  4. ADDED:1 REPLACED:1 REMOVED:2
  5. ADDED:1 REPLACED:2 REMOVED:2

 

Pokaż odpowiedź »

Poprawna jest odpowiedź nr 4.

Przeanalizujmy po kolei wartości dostępne w listenerze dla kolejnych etapów życia atrybutu. W przypadku dodania zachowanie jest chyba logiczne – otrzymujemy dokładnie taką wartość, jaką mu nadaliśmy. Sprawy nieco się komplikują przy nadpisaniu atrybutu. Logika podpowiada, że powinniśmy dostać nową wartość. Tak jednak się nie dzieje – uzyskujemy dostęp do wartości starej, która to została nadpisana. W momencie kiedy usuwamy atrybut, wartość dostępna dla listenera to ostatnia wartość usuwanego atrybutu.

Zdaj OCEWCD – pytanie 4

Jaki będzie efekt skompilowania i uruchomienia przedstawionego poniżej kodu servletu?

@WebServlet("/Test")
public class TestServlet extends HttpServlet
{
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        PrintWriter writer = response.getWriter();
        writer.println("Please wait, redirecting...");
        writer.flush();

        response.sendRedirect("http://www.javablog.eu");
    }
}

 

  1. Użytkownik zobaczy informację, po czym będzie przekierowany na javablog.eu.
  2. Użytkownik zobaczy pustą stronę, ponieważ rzucony zostanie wyjątek.
  3. Użytkownik zobaczy informację, po czym rzucony zostanie wyjątek.
  4. Kod nie skompiluje się.
  5. Użytkownik od razu zostanie przekierowany na stronę javablog.eu.

 

Pokaż odpowiedź »

Poprawna jest odpowiedź nr 3.

W linii siódmej piszemy do obiektu odpowiedzi, po czym w linii ósmej ją ‚zatwierdzamy’. W tym momencie response jest odsyłany do klienta, i nie jesteśmy już w stanie nic w nim zmienić. Próbujemy jednak tego w kolejnej linii – chcemy przekierować użytkownika na stronę javablog.eu. Kontener informuje nas o naszej pomyłce następującym wyjątkiem: java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed.

Zdaj OCEWCD – pytanie 3

Jaki będzie efekt działania przedstawionego poniżej kodu? Na potrzeby pytania załóżmy, że plik test.jsp istnieje i znajduje się na równi z katalogiem WEB-INF.

@WebServlet("/Test")
public class TestServlet extends HttpServlet
{
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        request.setAttribute("text", "Hello!");
        getServletContext().getRequestDispatcher("test.jsp").forward(request, response);
    }
}

 

  1. Kod nie skompiluje się, ponieważ ServletContext nie ma takiej metody.
  2. Użytkownik zostanie prawidłowo przekierowany na stronę test.jsp.
  3. Rzucony zostanie IllegalArgumentException.
  4. Kod nie skompiluje się, ponieważ metoda forward() ma inną sygnaturę.
  5. Kod nie skompiluje się, ponieważ metoda getRequestDispatcher() nie przyjmuje żadnych parametrów.

 

Pokaż odpowiedź »

Poprawna jest odpowiedź nr 3.

Powodem rzucenia takiego wyjątku jest niepoprawny argument przekazany metodzie getRequestDispatcher(). Co ciekawe, jeśli pozyskalibyśmy request dispatcher z obiektu request, kod działałby poprawnie. Dzieje się tak dlatego, iż ServletContext wymaga użycia ścieżki bezwzględnej przy wywołaniu metody getRequestDispatcher() (musi ona zaczynać się od znaku ‚/’). Inaczej jest w przypadku używania instancji HttpServletRequest – tutaj możliwe jest podanie ścieżki względem tej aktualnej. W ramach testu polecam podmienić linię 7 na poniższą:


request.getRequestDispatcher("test.jsp").forward(request, response);

Zdaj OCEWCD – pytanie 2

Poniżej znajduje się listing przedstawiający deskryptor wdrożenia (deployment descriptor) oraz kod servletu. Które z przedstawionych linii kodu wstawione w oznaczone miejsce pozwolą pobrać wartość parametru param_name? Tag <web-app> został celowo skrócony. Na potrzeby pytania należy założyć, że jest kompletny i poprawny.

<web-app ... >
   <context-param>
      <param-name>param_name</param-name>
      <param-value>some_value</param-value>
   </context-param>
</web-app>
@WebServlet("/Test")
public class TestServlet extends HttpServlet
{
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        // insert code to read parameter value here
    }
}

 

  1. Nie jest to możliwe.
  2. getServletConfig().getServletContext().getInitParameter(„param_name”);
  3. getServletConfig().getInitParameter(„param_name”);
  4. getServletContext().getInitParameter(„param_name”);
  5. getServletContext().getContextParameter(„param_name”);

 

Pokaż odpowiedź »

Poprawne są odpowiedzi 2 oraz 4.

Po pierwsze należy pamiętać o tym, że parametry definiowane przy użyciu tagu
<context-param> są, jak sama nazwa mówi, parametrami całego kontekstu aplikacji. Dostęp do nich można więc uzyskać poprzez ServletContext, a nie ServletConfig, który to jest tworzony dla każdego servletu z osobna. Służy do tego metoda getInitParameter(). Kolejną ważną kwestią są sposoby uzyskania dostępu do samego obiektu ServletContext. Wewnątrz servletu mamy dwa wyjścia – możemy wywołać bezpośrednio metodę getServletContext(), albo użyć dłuższego ciągu wywołań: getServletConfig().getServletContext(). Obydwie formy są poprawne.