JavaWeb

My day is done, and I am like a boat drawn on the beach,listening to the dance-music of the tide in the evening.

我的白昼已经完了,我象一只泊在海滩上的小船,谛听着晚潮跳舞的乐声。 

Java Web,是用Java技术来解决相关web互联网领域的技术栈。web包括:web服务端和web客户端两部分。Java在客户端的应用有Java Applet,不过使用得很少,Java在服务器端的应用非常的丰富,比如ServletJSP、第三方框架等等。Java技术对Web领域的发展注入了强大的动力。

JavaWeb

搭建Java Web应用的开发环境—–部署Tomcat服务器、用eclipse创建Server服务、构建Java Web项目、建立第一个JSP文件、 运行JSP文件。

第一个要点是掌握tomcat的安装和部署。

第二个要点是在IDEA中添加Server服务。把tomcat与IDEA进行关联,方便IDEA管理tomcat。

第三个要点是构建Java Web项目。Web项目开发的第一步就是要建立项目。

第四个要点是建立的项目如何在Server中运行。

Maven项目管理工具

Maven的核心思想:约定大于配置

`点击跳转Maven配值`

Servlet

点击跳转Servlet详解

Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。

狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。

最早支持Servlet标准的是JavaSoft的Java Web Server,此后,一些其它的基于Java的Web服务器开始支持标准的Servlet。

`点击跳转Servlet配值`

写一个Servlet程序

  1. 写一个类去继承父类HttpServlet
    HttpServlet是一个抽象类,但是没有任何抽象方法
    HttpServlet类中自定义了很多doXxxx方法,每一种方法都对应了浏览器发送请求的方法,一般常用的浏览器发请求方式为get和post,这两种方式分别对应了这个类中的doGet方法和doPost方法。
    HttpServlet类中,有两个service方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;

    public class ServletClass extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    PrintWriter writer = resp.getWriter(); //响应流
    writer.print("Hello,Serlvet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    super.doPost(req, resp);
    }
    }
  2. 在web.xml里面添加Servlet配置

    Servlet映射

    点击跳转servlet映射问题

    1
    2
    3
    4
    5
    6
    7
    8
    <servlet>
    <servlet-name>ServletClass</servlet-name>
    <servlet-class>com.bobo.servlet.ServletClass</servlet-class>
    </servlet>
    <servlet-mapping>
    <servlet-name>ServletClass</servlet-name>
    <url-pattern>/path</url-pattern>
    </servlet-mapping>
  3. 配置Tomcat

  4. 启动Tomcat服务

Servlet原理

Servlet的工作过程

步骤:

  1. Web Client 向Servlet容器(Tomcat)发出Http请求
  2. Servlet容器接收Web Client的请求
  3. Servlet容器创建一个HttpRequest对象,将Web Client请求的信息封装到这个对象中。
  4. Servlet容器创建一个HttpResponse对象
  5. Servlet容器调用HttpServlet对象的doservice方法,把HttpRequest对象与HttpResponse对象作为参数传给HttpServlet 对象。
  6. HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息。
  7. HttpServlet调用HttpResponse对象的有关方法,生成响应数据。
  8. Servlet容器把HttpServlet的响应结果传给Web Client。

Mapping问题

  • 一个Servlet可以指定一个映射路径

  • 一个Servlet可以指定多个映射路径

  • 一个Servlet可以指定通用映射路径

    1
    2
    3
    4
    <servlet-mapping> 
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello/*</url-pattern>
    </servlet-mapping>
  • 默认请求路径

    1
    2
    3
    4
    5
    <!--默认请求路径--> 
    <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/*</url-pattern>
    </servlet-mapping>
  • 指定一些后缀或者前缀

    1
    2
    3
    4
    5
    <!--可以自定义后缀实现请求映射 注意点,*前面不能加项目映射的路径--> 
    <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>*.bobo</url-pattern>
    </servlet-mapping>
  • 优先级问题

    指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <!--404--> 
    <servlet>
    <servlet-name>error</servlet-name>
    <servlet-class>com.bobo.servlet.ErrorServlet</servlet-class>
    </servlet>
    <servlet-mapping>
    <servlet-name>error</servlet-name>
    <url-pattern>/*</url-pattern>
    </servlet-mapping>

JSP

JSP(全称JavaServer Pages)是由Sun Microsystems公司主导创建的一种动态网页技术标准。JSP部署于网络服务器上,可以响应客户端发送的请求,并根据请求内容动态地生成HTMLXML或其他格式文档的Web网页,然后返回给请求者。JSP技术以Java语言作为脚本语言,为用户的HTTP请求提供服务,并能与服务器上的其它Java程序共同处理复杂的业务需求。

JSP将Java代码和特定变动内容嵌入到静态的页面中,实现以静态页面为模板,动态生成其中的部分内容。JSP引入了被称为“JSP动作”的XML标签,用来调用内建功能。另外,可以创建JSP标签库,然后像使用标准HTML或XML标签一样使用它们。标签库能增强功能和服务器性能,而且不受跨平台问题的限制。JSP文件在运行时会被其编译器转换成更原始的Servlet代码。JSP编译器可以把JSP文件编译成用Java代码写的Servlet,然后再由Java编译器来编译成能快速执行的二进制机器码,也可以直接编译成二进制码。

点击跳转JSP

MVC

点击跳转MVC三层架构

MVC指MVC模式的某种框架,它强制性地使应用程序的输入、处理和输出分开。使用MVC应用程序被分成三个核心部件:模型、视图、控制器。它们各自处理自己的任务。最典型的MVC就是JSP + servlet + JavaBean的模式。

视图View

负责页面的显示;与用户的交互。包含各种表单。

控制器Controller

控制器负责将视图与模型一一对应起来。相当于一个模型分发器。所谓分发就是:①接收请求,并将该请求跳转(转发,重定向)到模型进行处理。②模型处理完毕后,再通过控制器,返回给视图中的请求处。建议使用Servlet实现控制器。

模型Model

模型负责各个功能的实现(如登录、增加、删除功能)。模型用JavaBean实现。

JavaBeans :
①是Java中一种特殊的类(换言之:JavaBean就是一个Java类).
一个Java类 ,满足以下要求,则可称为一个JavaBean
a. public修饰的类,提供public 无参构造方法
b. 所有属性 都是private
c. 提供getter和setter方法

②从使用层面来看,JavaBean分为2大类:
a. 封装业务逻辑的JavaBean (eg:LoginDao.java 封装了登录逻辑)
b. 封装数据的JavaBean (实体类:eg:Student.java Vedio.java 。往往对应于数据库中的一张表,即数据库中有个Student表,项目中就有个Student.java类)

③JavaBean 是一个可以重复使用的组件,通过编写一个组件来实现某种通用功能,“一次编写、任何地方执行、任何地方重用”。

过滤器

过滤器如何编写

  1. 过滤器(Filter接口)是一个接口,所以需要一个实现这个接口的类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import javax.servlet.*;
    import java.io.IOException;

    public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

    }

    @Override
    public void destroy() {

    }
    }

    filterChain.doFilter()方法;
    执行目标资源,或是执行下一个过滤器!如果没有下一个过滤器那么执行的是目标资源,如果有,那么执行下一个过滤器

  1. 配置:在web.xml文件中配置,配置之后才会有效果,就如servlet一样

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>com.bobo.filter.MyFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>MyFilter</filter-name>
    <!--只要是/filter下面的任何请求都会经过这个过滤器-->
    <url-pattern>/filter/*</url-pattern>
    </filter-mapping>

    多个过滤器的执行顺序

    配置顺序决定了过滤器的执行顺序
    就是哪个文件在第一个,谁就是第一个执行

    过滤器的四种拦截方式

    • REQUEST 是默认的,当输入其他的,那么默认的将取消(消失)
    • 请求(拦的是直接请求,不拦转发请求):REQUEST
    • 转发(专门拦转发):FORWARD
    • 包含(专门拦包含):INCLUDE
    • 错误(专门拦错误):ERROR

Filter接口的生命周期

初始化(init())到使用(doFilter())到关闭之前(destroy())

  1. init(FilterConfig)
    什么执行:创建Filter之后,马上执行;
    什么时候创建呢:Filter会在服务器启动时就创建
  2. doFilter(ServletRequest,ServletResponse,FilterChain)
    什么时候执行:每次过滤时都会执行
  3. destroy()
    什么时候执行:在销毁之前执行
    什么时候销毁呢:在服务器关闭时销毁

当启动服务器时init方法马上执行了(在还没打开网页前已经执行了)
在过滤时(网页刷新时)才运行doFilter方法
当关掉服务器时执行destroy方法,就是当你点击关闭服务器是,就在执行了,伴随关闭一起执行

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import javax.servlet.*;
import java.io.IOException;

public class CharaterEncodingFilter implements Filter {
//初始化
//web服务启动就初始化
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharaterEncodingFilter初始化");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;charset=utf-8");
//chain链
//过滤中的所有代码,在特定请求的时候都会执行
//必须要让过滤器继续同行
System.out.println("CharaterEncodingFilter执行前");
filterChain.doFilter(servletRequest,servletResponse); //让我们的请求继续走,如果不写,程序到这里就会被拦截
System.out.println("CharaterEncodingFilter执行后");
}
//注销
//web服务器关闭时 过滤会注销
@Override
public void destroy() {
System.out.println("CharaterEncodingFilter注销");
}
}

通过监听获取Seesion中用户

因为要用到HttpServletRequest中的方法,所以对ServletRequest进行了强转,将ServletRequest servletRequest强制转换为子类

1
HttpServletRequest req = (HttpServletRequest) servletRequest;

此时有一些困惑:子类除了完全继承父类的方法外还会拓展自己的方法,所以我们在调用子类方法时可能在父类实现中是找不到的,所以向下转型不安全的。

其实doFilter的参数request对象的生成方式不是ServletRequest request = new ServletRequest();这种形式,而是ServletRequest request = new HttpServletRequest();这种形式,参数里的request不是父类ServletRequest的对象,而是HttpServletRequest的上转型对象。

在这篇博客中,博主给了很好的解释。

监听器

监听器就是监听某个对象的的状态变化的组件

  • 被监听的对象(三个域对象 request,session,servletContext)
  • 监听器:监听事件源对象, 事件源对象的状态的变化都会触发监听器 。
  • 注册监听器:将监听器与事件源进行绑定。
  • 响应行为:监听器监听到事件源的状态变化时,所涉及的功能代码(程序员编写代码)

监听器的编写步骤:

  1. 编写一个监听器类去实现监听器接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;

    public class MyListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {

    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {

    }
    }
  2. 覆盖监听器的方法

  3. 需要在web.xml中进行配置(注册)

    1
    2
    3
    4
    <!--    注册监听器-->
    <listener>
    <listenerclass>com.bobo.listenre.MyListener</listener-class>
    </listener>

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

//统计网站在线人数 --统计session
public class MyListener implements HttpSessionListener{
//创建session的监听
//一旦创建session就会触发一次
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
ServletContext ctx = httpSessionEvent.getSession().getServletContext();
System.out.println(httpSessionEvent.getSession().getId());
Integer onlineCount =(Integer) ctx.getAttribute("OnlineCount");
if (onlineCount==null){
onlineCount = new Integer(1);
}else {
int count = onlineCount.intValue();
onlineCount = new Integer(count+1);
}
ctx.setAttribute("onlineCount",onlineCount);
}
//销毁session的监听
//一旦销毁session就会触发一次
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
ServletContext ctx = httpSessionEvent.getSession().getServletContext();

Integer onlineCount =(Integer) ctx.getAttribute("OnlineCount");
if (onlineCount==null){
onlineCount = new Integer(1);
}else {
int count = onlineCount.intValue();
onlineCount = new Integer(count-1);
}
ctx.setAttribute("onlineCount",onlineCount);
}

// session销毁:
//1。手动销毁 httpSessionEvent.getSession().invalidate();
//2。自动销毁 web.xml中配置
}
1
2
3
4
5
6
7
8
9
<%@ page contentType="text/html; charset=utf-8" language="java" %>
<html>
<head>
<title> Title </title>
</head>
<body>
<h1>当前有<span><%=this.getServletConfig().getServletContext().getAttribute("onlineCount")%></span>人在线</h1>
</body>
</html>

文件上传

首先导入commons-io-版本.jarcommons-fileupload-版本.jar

注意事项:

  1. 为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下。
  2. 为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名。
  3. 为防止一个目录下面出现太多文件,要使用hash算法打散存储。
  4. 要限制上传文件的最大值。
  5. 要限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。

通过表单上传文件

  • get 上传文件大小有限制
  • post 上传文件大小没有限制

必须要用 post 进行提交,这种方式,将会把数据封装在请求体中进行发送。

使用的类

  1. FileItem类

    表单如果包含一个文件上传输入选项,这个表单的enctype属性必须设置为enctype="multipart/form-date"

  2. ServletFileUpload类

    负责处理上传的文件数据,并将表单中的每个输入项封装成一个FileItem对象,使用parseRequest(HttpServletReqquest)方法可以将通过表单中的每一个HTML标签提交的数据封装成一个FileItem对象,然后以List列表的形式返回。

    在使用ServletFileUpload对象解析请求时需要DiskFileItemFactory对象,所以,我们需要在进行解析工作前构造好DiskFileItemFactory对象,并通过ServletFileUpload对象的构造方法或setFileItemFactory()方法设置ServletFileUpload对象的fileItmlFactory属性。

博文推荐

查看评论