• Servlet和Jsp


    servlet和CGI

    我们知道Web服务器(如apache)只擅长提供静态页面,因此在动态应用场景,Web服务器会把请求转发给另一个能够动态处理的辅助应用(helper app),这个辅助应用就是CGI,而CGI可以用C、Python、PHP、Perl等等来实现。请求和应答如下图:

    而Java的CGI实现就是Servlet,如下图:

    由于servlet没有main()方法,因此它受控于web Container app(容器),而Tomcat就是一个这样的容器。Tomcat容器的作用提供通信支持、声明周期管理、多线程支持、声明方式实现安全、JSP支持等,看参考Tomcat初识。它的流程是这样的:

    1. Client发出一个请求到WebServer;
    2. WebServer接收到请求好转发给Web Container;
    3. Web Container根据URL在部署描述文件(web.xml)中找到对应的servlet;
    4. Web Container调用对相应的servlet的service()方法;
    5. servlet的service()方法根据请求的类型get/post调用相应的处理逻辑;
    6. 处理完毕后servlet返回结果;

    servlet实例

    1. 构建项目

      我们使用Eclipse+Maven来构建Java的servlet应用,以前曾经写过一篇超入门级的:maven + eclipse + tomcat 实战JSP,文章里使用的maven构建再导入到eclipse中,当然你也可以从eclipse来使用maven插件来构建项目,我的测试项目如下:

      如果提示错误

      The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path

      这是因为没有添加servlet类库,可以在pom添加servlet的依赖库,也可以添加server runtime的tomcat server.

      默认的部署文件web.xml

      <!DOCTYPE web-app PUBLIC
       "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
       "http://java.sun.com/dtd/web-app_2_3.dtd" >
      
      <web-app>
        <display-name>Archetype Created Web Application</display-name>
      </web-app>
    2. 运行

      建立完毕后我们可以通过Run As -> Run on Server就可以浏览index.jsp了(我用的Eclipse是Eclipse Java EE IDE for Web Developers.),显示“Hello World!”。

      添加Servlet:项目"mytest"右键->New->Other->Web->Servlet,ClassName填上“HelloOther”,Next会让设置URL路径,初始值等,再Next可以看到你需要的方法如doGet、doPost等,Finish后你会看到web.xml:

      <!DOCTYPE web-app PUBLIC
       "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
       "http://java.sun.com/dtd/web-app_2_3.dtd" >
      
      <web-app>
        <display-name>Archetype Created Web Application</display-name>
        <servlet>
        	<servlet-name>HelloOther</servlet-name>
        	<display-name>HelloOther</display-name>
        	<description></description>
        	<servlet-class>net.oseye.web.HelloOther</servlet-class>
        </servlet>
        <servlet-mapping>
        	<servlet-name>HelloOther</servlet-name>
        	<url-pattern>/HelloOther</url-pattern>
        </servlet-mapping>
      </web-app>
      如上述原理,当Clinet请求”/HelloOther“时,Web Container会在部署描述文件web.xml中寻找servlet-name为的HelloOther的servlet配置,再找到处理这个请求的servlet类“net.oseye.web.HelloOther”。

      net.oseye.web.HelloOthe类的doGet方法体中编码:

      response.getWriter().println("Hello Other!");
      你访问”/HelloOther“就能看到结果了。
    3. 打包WAR    

      可以使用mvn命令创建WAR包:

      mvn package
      也可以使用Eclipse的Export菜单来导出WAR包。

    PS:这里我们只使用Tomcat,没看到使用Web Server呀?这是因为Tomcat本身就具有基本的HTTP服务器的功能,只是没有Apache等专业的Web Server健壮和完整。

    简单的MVC

    前面的示例我们在servlet中使用了

    response.getWriter().println("Hello Other!");

    但如果是整个HTML页面将会非常麻烦,因此我们考虑使用MVC架构,servlet充当Controller角色,JSP充当View,Java Class充当Model,结构图如下:

    通过Controller(servlet)从Model(DB)中获取数据,然后把数据包装成Servlet的请求属性,然后把请求(request和reponse)转发至Jsp(View),JSP生成一个HTML页面,并使用应答对象(response)返回至容器,示例图如下:

    接着上面的示例代码,net.oseye.web.HelloOthe类的doGet方法体中编码:

    request.setAttribute("word", "Hello Other!");
    RequestDispatcher view=request.getRequestDispatcher("HelloOther.jsp");
    view.forward(request, response);

    HelloOther.jsp的代码如下:

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <!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=ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>
    <%=request.getAttribute("word")%>
    </body>
    </html>

    这就实现了MVC结构,项目结构图如下:

    后记

    1. ServletConfig和ServletConext
      Servlet的无参构造函数只是让Servlet变成一个对象,而init()方法让其成为一个Servleet对象,每个Servlet都有一个ServletConfig对象,用于访问部署配置文件信息,而且可以通过ServletConfig对象访问ServletContext。每个Web应用都有一个ServletContext对象,用来访问容器相关信息以及部署配置文件,其实ServletContext称为AppContext更合适一些。
      部署(DD)文件web.xml是这样的:
      <!DOCTYPE web-app PUBLIC
       "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
       "http://java.sun.com/dtd/web-app_2_3.dtd" >
      
      <web-app>
        <display-name>Archetype Created Web Application</display-name>
        <context-param>
        	<param-name>email</param-name>
        	<param-value>kevin@oseye.net</param-value>
        </context-param>
      
        <servlet>
        	<servlet-name>HelloOther</servlet-name>
        	<display-name>HelloOther</display-name>
        	<description></description>
        	<servlet-class>net.oseye.web.HelloOther</servlet-class>
        	<init-param>
        		<param-name>tel</param-name>
        		<param-value>13910567832</param-value>
        	</init-param>
        </servlet>
      
        <servlet-mapping>
        	<servlet-name>HelloOther</servlet-name>
        	<url-pattern>/HelloOther</url-pattern>
        </servlet-mapping>
      
      </web-app>
      可以在net.oseye.web.HelloOther的doGet中编码获取:
      String tel=getServletConfig().getInitParameter("tel");
      String email=getServletContext().getInitParameter("email");
      response.getWriter().println("tel:"+tel+",email:"+email);
    2. 应答除了分派给JSP,还可以使用PrintWriter和ServletOutputStream,前者是字符,后者是流。获取方式:
      PrintWriter pr=response.getWriter();
      ServletOutputStream os=response.getOutputStream();
    3. 请求和应答常用的方法
      request.getParameter(arg0) //获取get/post参数值
      request.getHeader(arg0) //获取头信息
      request.getCookies() //获取cookies
      request.getSession() //获取session
      request.getRequestDispatcher(arg0) //分派请求
      
      response.sendRedirect(String arg0) //重定向
      response.setHeader(String arg0, String arg1) //设置头信息,如果重复就替换
      response.addHeader(String arg0, String arg1) //添加头信息
      response.setContentType(arg0) //设置ContentType,避免手动拼写错误
  • 相关阅读:
    基于RMAN从活动数据库异机克隆(rman duplicate from active DB)
    包含min函数的栈
    栈的链表实现
    HDU 2196 树形DP Computer
    linux之access函数解析
    [置顶] sqlplus 使用笔记
    仿新浪微博登陆邮箱提示效果!
    找出数组中出现奇数次的元素<异或的应用>
    SOA体系结构基础培训教程-规范标准篇
    一个寻找.jar 和.zip文件中class文件的工具
  • 原文地址:https://www.cnblogs.com/zhaiqianfeng/p/4622466.html
Copyright © 2020-2023  润新知