Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // http://ocejwcd.wikidot.com/
- //3306 A 4792 2 DIAS TA BOM!
- //CAPITULO 5 ATTRIBUTES AND LISTENERS: BEING A WEB APP
- Init parameters
- DD->
- <servlet>
- ....
- <init-param>
- <param-name>adminEmail</param-name>
- <param-value>thiago@hotmail.com</param-value>
- </init-param>
- </servlet>
- In the servlet
- getServletConfig().getInitParameter("adminEmail");
- //podemos chamar o getServletConfig() de qualquer lugar do nosso servlet, menos do construtor, só
- //podemos depois do init() terminar, ou seja, do service() pra frente
- Unico servletConfig por servlet
- O container le os init parameters do DD e mandam para o servletconfig. Depois o container passa o servletconfig para o init(ServletConfig);
- O init() que devemos sobrescrever nao leva parametro nenhum. O que leva o init(ServletConfig) chama o init() internamente.
- Se sobrescrever o outro, temos que chamar o init() la dentro para nao dar cagada!
- Esses parametros são lidos uma única vez, e só quando o container initializes the servlet.
- O container nunca vai ler os init parameters de novo.
- ENTÃO COMO NÃO LÊ DE NOVO, TEMOS QUE DAR UM REDEPLOY PARA OS DADOS NOVOS COMEÇAREM A VALER.
- interface javax.servlet.ServletConfig
- getInitParameter(String);
- Enumeration getInitParameterNames();
- getServletContext();
- getServletName();
- DD web.xml
- ...
- <servlet>
- <servlet-name>BeerParamTests</servlet-name>
- <servlet-class>com.example.TestInitParams</servlet>
- ....
- <init-param>
- <param-name>adminEmail</param-name>
- <param-value>admin@hotmail.com</param-value>
- </init-param>
- <init-param>
- <param-name>mainEmail</param-name>
- <param-value>thiago@hotmail.com</param-value> //TESTAR DOOIS ATRIBUTOS COM O MESMO NOME!
- </init-param>
- <servlet-mapping>
- <servlet-name>BeerParamTests</servlet-name>
- <url-pattern>/Tester.do</url-pattern>
- </servlet-mapping>
- </servlet>
- public class TestInitParams extends HttpServlet {
- ....
- public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
- response.setContentType("text/html");
- Enumeration e = getServletConfig().getInitParameterNames();
- while (e.hasMoreElements()){
- e.nextElement(); //vai printar os parameters names mainEmail e adminEmail
- }
- String adminEmail = getServletConfig().getInitParameter("adminEmail");
- }
- }
- How can a JSP get servlet init parameters? Servlet init params são exclusivos para o servlet, se tentar pegar o atributo em outro, da cagada!
- Para esse caso setamos o atributo no Context initParam e nao no servletConfig. Esses parametros sao de toda a webapp.
- Então todo servlet e jsp tem acesso a ele.
- No dd web.xml ficaria assim
- ...
- <servlet>
- ...
- </servlet>
- <context-param>
- <param-name>adminEmail</param-name>
- <param-value>clienteheaderror@hotmail.com</param-value>
- </context-param>
- ****IMPORTANTE, O Context PARAM NAO FICA DENTRO DE UM SERVLET, DIFERENTE DO <init-param>
- Para acessar no servlet
- getServletContext().getInitiParameter("adminEmail");
- Difference between servlet init parameters and context init parameters.
- Context fica dentro do webapp e fora dos servlet.
- Init fica dentro de um servlet e so vale para aquele servlet.
- <init-param> <context-param>
- getServletConfig().getInitParameter("meuParametro") -> initParam VALE APENAS PARA O SERVLET ESPECIFICO.
- getServletContext().getInitParameter("meuParametro") -> contextParam VALE PARA TODA A APP.
- Web app initialization
- Container reads DD and create name/value for each <context-param>
- Container creates a new instance of ServletContext
- Container gives the ServletContext a reference for each name/value
- Every jsp and servlet has access to taht same ServletContext
- Um único ServletContext por JVM em caso de aplicações distribuidas.
- Think of init parameters as deploy-time constants. You can get them at runtime, but you cant set them. NAO TEMOS METODOS setInitiParameter();
- *ContextParameter, application parameter , context init param.
- *Servlet init parameter, init parameter, servlet init param.
- interface ServletContext {
- getInitParameter(String);
- getInitParameterNames();
- getAttribute(String);
- getAttributeNames();
- setAttribute(String, Object);
- removeAttribute(String);
- getMajorVersion()
- getServletInfo();
- getRealPath();
- getResourceAsStream(String);
- getRequestDispatcher(String);
- log(String);
- }
- Podemos pegar o servletContext() de duas formas também!
- getServletConfig().getServletContext()
- ou
- this.getServletContext();
- UNICA VEZ QUE TEMOS QUE BUSCAR O CONTEXT ATRAVES DO CONFIG É QUANDO ESTAMOS EM UM SERVLET QUE NAO EXTENDS HTTPSERVLET OR GENERICSERVLET.
- Todos os init param são String!
- Como fazer que algo rode antes de um servlet ou jsp em especifico? Usar listener e GG
- We wants to listen for a context initialization event, so that can get the context init parameters and run some
- code before the rest of the app can service a client.
- Como se fosse um main, quero que algo rode antes de qualquer coisa, como fazer?
- Usamos um ServletContextListener
- interface ServletContextListener {
- contextInitilized(ServletContextEvent);
- contextDestroyed(ServletContextEvent);
- //javax.servlet.ServletContextListener
- }
- This listener can:
- Get notified when the context is initialized
- Get the init param from the context
- Use the init param to make a db connection.
- Get notified when the context is destroyed.
- import javax.servlet.*;
- public class MyServletContextListener implements ServletContextListener {
- public void contextInitilized(ServletContextEvent event){
- ServletContext context = event.getServletContext();
- ...
- Dog d = new Dog(); //SE FOSSE APP DISTRIBUIDA, DOG TERIA QUE SER SERIALIZABLE!
- ....
- event.setAttribute("dog", d); //É ATRIBUTO, TEM SET E É OBJETO!!!!
- //FOI SETADO NO CONTEXT, ENTAO PARA PEGAR TEMOS QUE BUSCAR NO context.getAttribute("dog"); FAZENDO O CAST!, LEMBRAR Q RETORNA OBJECT!
- //PARAM NAO TEM SET E SÓ PODE SER STRING!
- }
- public void contextDestroyed(ServletContextEvent event){
- //code to close the db connection.
- }
- }
- Para o listener ser "visto" temos que por no nosso DD.
- dentro do web app, fora dos servlet e de qualquer outra coisa, no root mesmo do <web-app>
- <listener>
- <listener-class>com.example.MyServletContextListener</listener-class>
- </listener>
- Outras listeners interfaces e seus eventos que podem ser "ouvidos"
- HttpSessionAttributeListener HttpSessionBindingEvent-> atributeAdded/Removed/Replaced aqui é quando um atributo normal
- que nao seja um objeto de uma classe.
- ServletRequestListener ServletRequestEvent-> para saber quando ocorre uma request.
- HttpSessionBindingListener HttpSessionBindingEvent-> valueBound valueUnbound ! quando é add ou removido da session !
- !objeto de uma classe que sera guardado!!
- ServletContextAttributeListener ServletContextAttributeEvent-> quando um attributo é add, removed or replaced esse evento ocorre!
- HttpSessionListener HttpSessionEvent-> para saber por exemplo quantos users estao no sistema.
- ServletRequestAttributeListener ServletRequestAttributeEvent-> quando um atributo é add, removido ou replaced em uma request.
- ServletContextListener ServletContextEvent-> quando o contexto é inicializado ou destruido.
- HttpSessionActivationListener HttpSessionEvent-> an attribute class, e quero q seja notificado quando estiver pronto
- para migrar para outra JVM
- ;{}
- interface ServletContextAttributeListener { //EVENTO ServletContextAttributeEvent
- void attributeAdded(ServletContextAttributeEvent event);
- void attributeRemoved(ServletContextAttributeEvent event);
- void attributeReplaced(ServletContextAttributeEvent event);
- }
- interface HttpSessionListener { //EVENTO HttpSessionEvent
- void sessionCreated(HttpSessionEvent event);
- void sessionDestroyed(HttpSessionEvent event);
- }
- interface ServletRequestListener { //EVENTO ServletRequestEvent
- void requestInitialized(ServletRequestEvent event);
- void requestDestroyed(ServletRequestEvent event);
- }
- interface ServletRequestAttributeListener { //EVENTO ServletRequestAttributeEvent
- void attributeAdded(ServletRequestAttributeEvent event);
- void attributeRemoved(ServletRequestAttributeEvent event);
- void attributeReplaced(ServletRequestAttributeEvent event);
- }
- interface HttpSessionBindingListener { //EVENTO HttpSessionBindingEvent
- void valueBound(HttpSessionBindingEvent event) //AQUI SAO OBJETOS DE CLASSES QUANDO SAO INSERIDAS OU REMOVIDAS DA SESSION!
- void valueUnbound(HttpSessionBindingEvent event);
- }
- interface HttpSessionAttributeListener { //EVENTO HttpSessionBindingEvent *****************
- void attributeAdded(HttpSessionBindingEvent event); //AQUI SAO ATRIBUTOS NORMAIS
- void attributeRemoved(HttpSessionBindingEvent event);
- void attributeReplaced(HttpSessionBindingEvent event);
- }
- interface ServletContextListener {//EVENTO ServletContextEvent
- void contextInitilized(ServletContextEvent event);
- void contextDestroyed(ServletContextEvent event);
- }
- interface HttpSessionActivationListener { //EVENTO HttpSessionEvent ******************
- void sessionDidActivate(HttpSessionEvent event);
- void sessionWillPassivate(HttpSessionEvent event);
- }
- REPARAR QUE no HttpSessionActivationListener e no HttpSessionAttributeListener OS EVENTOS NAO SEGUEM OS NOMES PADRÃO!!!!!
- HttpSessionAttributeListener x HttpSessionBindingListener
- In HttpSessionAttributeListener any type of attribute has ben added, removed or replaced.
- In HttpSessionBindingListener the attribute itself can find out when it has been added to or removed from a session.
- public class Dog implements HttpSessionBindingListener {
- private String breed;
- public void valueBound(HttpSessionBindingEvent event){
- }
- public void valueUnbound(HttpSessionBindingEvent event){
- }
- } //NOW DOG IS A LISTENER! toda vez que dog for para a session ou sair, vamos ser notificados aqui!!! SACOU O BINDINGLISTENER PARA QUE SERVE? PARA A CLASSE EM SI!
- // BINDINGLISTENER ARE NOT REGISTERED IN DD!!!!
- //3997 PRIMEIRA PARADA
- An attribute is an object set into onte of three other servlet API objects, ServletContext, HttpServletRequest/ServletRequest or HttpSession.
- Attributes are not parameters.
- Attributes Parameters
- Types Application/Context Application/Context init parameters
- Request Request Parameters
- Session Servlet init Parameters
- There is no servlet specific attr No such thing as session parameters.
- Set? setAttribute(String,Object) CANNOT SET, just in DD.
- Return Object String
- Get? ServletContext.getAttribute(name) ServletContext.getInitParameter(name)
- HttpSession.getAttribute(name) ServletConfig.getInitParameter(name)
- ServletRequest.getAttribute(name) ServletRequest.getInitParameter(name)
- Os três scopes são?
- Context-> vale para toda a web app. De todo lugar conseguimos pegar ou setar!
- Session -> somente para os que tem acesso a aquela httpSession.
- Request -> somente para aquela request, depois ele "some".
- Os metodos comuns nas interfaces são:
- Object getAttribute(String name);
- void setAttribute(String name, Object value);
- void removeAttribute(String name);
- Enumeration getAttributeNames();
- interface ServletContext {
- getInitParameter(String);
- getInitParameterNames();
- Object getAttribute(String name);
- void setAttribute(String name, Object value);
- void removeAttribute(String name);
- Enumeration getAttributeNames();
- getMajorVersion();
- getServerInfo();
- getResourceAsStream();
- getRequestDispatcher();
- log(String);
- ...
- }
- interface ServletRequest {
- getContentType();
- getInitParameter(String name);
- Object getAttribute(String name);
- void setAttribute(String name, Object value);
- void removeAttribute(String name);
- Enumeration getAttributeNames();
- ...
- }
- interface HttpServletRequest extends ServletRequest {
- nothing related to attributes here..
- getContextPath();
- getCookies();
- getHeader(String);
- getSession();
- gerQueryString();
- ...
- }
- interface HttpSession {
- Object getAttribute(String name);
- void setAttribute(String name, Object value);
- void removeAttribute(String name);
- Enumeration getAttributeNames();
- setMaxInactiveInterval(int);
- getId();
- getLastAccessedTime();
- ...
- }
- DarkSide of attributes.
- In a servlet
- ....
- getServletContext().setAttribute("foo", "22");
- getServletContext().setAttribute("bar", "42");
- out.println(getServletContext().getAttribute("foo"));
- out.println(getServletContext().getAttribute("bar"));
- //nothing wrong, print 22 and 42 for the first time run.
- **If we run again
- Printed out 22 and 16.
- O que pode ter dado de errado? Colocamos esse codigo em um app grande, com varios outros servlets, então, algum outro servlet pode ter setado esse valor
- de 16 para o atributo bar! Como ele é de scope context, a aplicação toda o enxerga!
- *Context scoped isnt thread-safe!
- How do we make context attributes thread-safe?
- 1-> Synchronizing the doGet()/doPost()... methods is a bad idea.
- Garantimos que ninguem va alterar os atributos ALI, porém, como o servlet é unico... imagina em um site grande....
- Em outro lugar as pessoas pode alterar esses valores, como sao atributos de context.
- Não precisamos de um lock no servlet e sim no context!
- Dentro do servlet usaremos entao synchronized(getServletContext()){ BLA BLA BLA } Assim garantimos, porém, todos terão que implementar assim.
- Are session attributes thread-safe?
- A session dura por multiplas request de um mesmo cliente. Nada impede o cliente de abrir duas janelas e fazer varias requests. Essa é a unica forma
- de dar cagada em sessionAttributes. Para proteger disso, podemos synchronized (request.getSession()) {}
- SingleThreadModel is designed to protect instance variables (STM interface).
- public class MeuServlet extends HttpServlet implements SingleThreadModel {}
- Isso faz com que o container trabalhe com um request por vez para esse servlet.
- Essa interface não tem methods, apenas garante isso.
- Para isso temos duas abordagens:
- 1) The container maintain a single servlet, but queue every request and process one request completely before the next request to proceed.
- 2) The container creates a pool of servlet instances and procces each request concurrently, one per servlet instance.
- A primeira-> faz uma queue de request para o servlet e vai processando conforme forem ficando prontas
- A segunda-> faz um pool de request e cada uma vai para uma instance do mesmo servlet, para ser processada.
- So, only request attribute and local variables are thread-safe.
- STM garante que apenas uma thread daquele servlet vai existir.
- Request attributes and Request dispatching.
- Request attributes applies only in one request, after it, all dies.
- request.setAttribute("styles", result);
- RequestDispatcher view = request.getRequestDispatcher("result.jsp");
- view.forward(request, response);
- ESSE ATRIBUTO SO VIVE AQUI, OU SEJA SO VAI EXISTIR NESSE SERVLET E NA JSP "RESULT.JSP".
- RequestDispatcher have only two methods.
- forward(request,response);
- include(request,response); //veremos no <jsp: include> é o mesmo metodo!
- Podemos pegar o Dispatcher do request e do context.
- request.getRequestDispatcher("minhaPagina.jsp"); //se fosse /minhaPagina.jsp ele tentaria root/minhaPagina.jsp.
- getServletContext().getRequestDispatcher("/result.jsp"); //vai tentar rootdaApp/result.jsp
- **QUANDO PEGAMOS DO CONTEXT, TEMOS QUE USAR O / NO NOSSO PATH, SE NAO DA CAGADA!!!!
- in a servlet code
- ...
- OutputStream os = response.getOutputStream();
- ....
- RequestDispatcher view = request.getRequestDispatcher("result.jsp");
- os.flush();
- view.forward(request, response);
- os.close();
- Qual a merda no codigo? Vamos receber uma linda IllegalStateException, ja comitamos a response com o flush() e tentamos passar A request no forward.
- NAO PODEMOS DAR FORWARD NA REQUEST APOS A RESPONSE SER ENVIADA!
- **You cant forward the request if youve already commited a response.
- //TESTAR CHAMAR O GETSERVLETcONFIG NO INIT();
- V <init-param>
- <param-name>adminEmail</param-name>
- <param-value>admin@hotmail.com</param-value>
- </init-param>
- <init-param>
- <param-name>mainEmail</param-name>
- <param-value>thiago@hotmail.com</param-value> //TESTAR DOOIS ATRIBUTOS COM O MESMO NOME!
- </init-param>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement