java web 订阅
Java Web,是用Java技术来解决相关web互联网领域的技术栈。web包括:web服务端和web客户端两部分。Java在客户端的应用有java applet,不过使用得很少,Java在服务器端的应用非常的丰富,比如Servlet,JSP和第三方框架等等。Java技术对Web领域的发展注入了强大的动力。 展开全文
Java Web,是用Java技术来解决相关web互联网领域的技术栈。web包括:web服务端和web客户端两部分。Java在客户端的应用有java applet,不过使用得很少,Java在服务器端的应用非常的丰富,比如Servlet,JSP和第三方框架等等。Java技术对Web领域的发展注入了强大的动力。
信息
优    点
上手快速并且相对容易
主要框架
使用Servlet或者Filter拦截请求
包    括
web服务器和web客户端
中文名
java web
应    用
Servlet,JSP
java web主要框架
Java的Web框架虽然各不相同,但基本也都是遵循特定的路数的:使用Servlet或者Filter拦截请求,使用MVC的思想设计架构,使用约定,XML或 Annotation实现配置,运用Java面向对象的特点,面向对象实现请求和响应的流程,支持Jsp,Freemarker,Velocity等视图。Java EE标准,这意味着有很大的市场需求和更多的工作机会上手快速并且相对容易有大量可用的组件库大量的JSP标签对REST和安全支持不好没有一个统一的实现。既有SUN的实现,又有Apache的实现——MyFaces。对Spring MVC覆盖绑定(overriding binding)、验证(validation)等提供生命周期管理与许多表示层技术/框架无缝集成:JSP/JSTL、Tiles、Velocity、FreeMarker、Excel、XSL、PDF 等便于测试——归功于IoC大量的XML配置文件太过灵活——没有公共的父控制器没有内置的Ajax支持不需要书写XML配置文件良好的学习文档社区成员很热心社区比较小不如其他的项目活跃ActionBean里面的URL是硬编码的架构简单——易于扩展标记库很容易利用FreeMarker或者Velocity来定制基于控制器或者基于页面的导航文档组织得很差对新特征过分关注一旦学会它,将极大地提高生产率HTML模板——对页面设计师非常有利每出一个新版本,都会有大量的创新文档过于概念性,不够实用学习曲线陡峭发行周期长——每年都有较大的升级对Java开发者有利(不是Web开发者)页面和显示绑定紧密社区活跃——有来自创建者的支持HTML模板和Java代码紧挨着需要对OO有较好的理解Wicket逻辑——什么都用Java搞定
收起全文
精华内容
参与话题
问答
  • JavaWeb是什么?总结一下JavaWeb的体系

    万次阅读 多人点赞 2018-10-23 10:12:56
    通过最近在尚硅谷上学习,分享一下Java WEB前言JavaWeb的技术体系登录页面的开发涉及的技术知识点HTML是什么?登录功能实现-环境的搭建涉及的技术知识点Web服务器Tomcat服务器的安装及配置在eclipse中配置tomcat创建...

    Java WEB

    前言

    Java Web 其实就是一个技术的总和,把Web看成一个容器而已主要使用JavaEE技术来实现.在加上各种中间件。整个javaWeb阶段的内容通过实际的案例贯穿学习, 所涉及到的技术知识点会在案例中根据不同的需求引入。首先了解javaWEB的整个技术体系,掌握常用的技术知识点。

    JavaWeb的技术体系

    体系
    下面我们以登录功能的实现来讲讲JavaWeb

    登录页面的开发

    涉及的技术知识点

    • HTML

    HTML是什么?

    1. HTML指的超文本标记语言(Hyper Text Markup Language),是一种用来描述网页的语言。超文本指的是除了可以包含文字之外,还可以包含图片、链接、音乐、视频、程序等内容。

    2. HTML网页的组成:
      html

    3. 常用的HTML标签
      ①html 根标记
      ②head 头标记
      ③body 体标记
      ④a 超链接
      ⑤form 表单
      ⑥table 表格

    4. 一个基本结构的HTML页面
      html

    5. 登录页面的示例
      login.html

    登录功能实现-环境的搭建

    涉及的技术知识点

    • WEB服务器
      • 动态的web工程

    Web服务器

    • 1. Web服务器主要用来接收客户端发送的请求和响应客户端请求。
    • 2. Tomcat(Apache)( 我们主要撸这只猫 ):当前应用最广的JavaWeb服务器;
    • 3. JBoss(Redhat红帽):支持JavaEE,应用比较广EJB容器 –> SSH轻量级的框架代替
    • 4. GlassFish(Orcale):Oracle开发JavaWeb服务器,应用不是很广;
    • 5. Resin(Caucho):支持JavaEE,应用越来越广;
    • 6. Weblogic(Orcale):要钱的!支持JavaEE,适合大型项目;
    • 7. Websphere(IBM):要钱的!支持JavaEE,适合大型项目

    Tomcat服务器的安装及配置

    1. 将Tomcat的安装包解压到磁盘的任意位(非中文无空格)
    2. Tomcat服务的目录结构
      Tomcat
    3. 配置环境变量,方便Tomcat的启动关闭(可选)
      ①新建环境变量CATALINA_HOME=解压目录
      home
      在Path环境变量中加入Tomcat解压目录\bin目录
      在这里插入图片描述
      ③在命令行中运行catalina run或者 startup启动Tomcat服务器,在浏览器地址栏访问如下地址进行测试
      http://localhost:8080
      tomcat

    在eclipse中配置tomcat

    1. 在Eclipse中配置运行环境
      在这里插入图片描述
    2. 在Eclipse中创建新的Server
      在这里插入图片描述
      在这里插入图片描述

    创建动态的web工程

    1. 在Eclipse中点击File ->New->Dynamic Web Project
      在这里插入图片描述
      Dynamic web module version我们学习阶段就选2.5通过配置编程,到后期我们再选3.0通过注解编程
      在这里插入图片描述

    记得一定要勾选

    登录功能实现-LoginServlet

    涉及的技术知识点

    1. Servlet
    2. Request请求对象
    3. Response响应对象

    什么是Servlet?

    1. Servlet是Sun公司制定的一套技术标准,包含与Web应用相关的一系列接口,是Web应用实现方式的宏观解决方案。而具体的Servlet容器负责提供标准的实现。
    2. Servlet作为服务器端的一个组件,它的本意是“服务器端的小程序”。Servlet的实例对象由Servlet容器负责创建;Servlet的方法由容器在特定情况下调用;Servlet容器会在Web应用卸载时销毁Servlet对象的实例。
    3. 简单可以理解为 Servlet就是用来处理客户端的请求的.
    4. 狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。

    Servlet开发规则

    实际编码通过继承HttpServlet来完成Servlet的开发

    public class LoginServlet extends HttpServlet{
    }
    

    Servlet类的相关方法:

    doGet Servlet中用于处理get请求的方法

    @Override
    	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		super.doGet(req, resp);
    	}
    

    doPost Servlet中用于处理post请求的方法

    @Override
    	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	super.doPost(req, resp);
    }
    

    service
    ①在Servlet的顶层实现中,在service方法中调用的具体的doGet或者是doPost
    ②在实际开发Servlet的过程中,可以选择重写doGet以及doPost 或者 直接重写service方法来处理请求。

    Servlet在web.xml中的配置

    Servlet

    获取请求参数值

    HttpServletRequest
    ①该接口是ServletRequest接口的子接口,封装了HTTP请求的相关信息,由Servlet容器创建其实现类对象并传入service(ServletRequest req, ServletResponse res)方法中。以下我们所说的HttpServletRequest对象指的是容器提供的HttpServletRequest实现类对象。
    ②HttpServletRequest对象的主要功能有

    • 获取请求参数
    • 在请求域中绑定数据
    • 将请求转发给另外一个URL地址 [转发]

    响应结果

    HttpServletResponse
    ①该接口是ServletResponse接口的子接口,封装了HTTP响应的相关信息,由Servlet容器创建其实现类对象并传入service(ServletRequest req, ServletResponse res)方法中。以下我们所说的HttpServletResponse对象指的是容器提供的HttpServletResponse实现类对象
    ②主要功能

    • 使用PrintWriter对象向浏览器输出数据
    • 实现请求的重定向[重定向]

    具体登录功能的实现步骤

    1. 在登录页面中录入用户名和密码,点击登录按钮提交登录请求
      在这里插入图片描述
    2. 在LoginServlet中通过request对象获取到页面表单提交的用户名和密码
    3. 调用Dao对象,将用户提交的用户名和密码与数据库的用户表的数据进行匹配
    4. 得出结果,完成响应.
    package com.atguigu.login.servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.atguigu.login.beans.User;
    import com.atguigu.login.dao.UserDao;
    import com.atguigu.login.dao.UserDaoImpl;
    
    /*
     * 处理登录请求的Servlet
     * 
     * Servlet是sun公司制定的标准。Tomcat(web应用服务器、Servlet容器)实现了这些标准。
     * 
     * HttpServlet
     */
    public class LoginServlet extends HttpServlet{
    	/**
    	 * 常用的方法:doGet doPost service
    	 * 
    	 * 第一种方法  重写
    	 *  doGet:处理客户端的get方式的请求
    	 *  doPost:处理客户端的post方式的请求
    	 *  
    	 *  第二种方法  重写
    	 *  service:根据具体的请求方法去调用对应的doGet、doPost方法
    	 *  
    	 */
    	@Override
    	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		doPost(req, resp);
    	}
    	@Override
    	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		//登录功能的实现。
    		System.out.println("登录请求来了~~~~~~~~~~~");
    		//获取到用户输入的用户名的密码,进行登录业务的处理
    		/*
    		 * HttpServletRequest: 请求对象。Servlet容器会在请求到达后,创建出一个request对象,将
    		 * 							Http请求相关的信息全部都封装到该对象中。
    		 */
    		//获取用户输入的用户名和密码
    		String username =  req.getParameter("username");
    		String password =  req.getParameter("password");
    		//调用Dao对象,将用户提交的用户名和密码与数据库的用户表的数据进行匹配
    		UserDao dao = new UserDaoJdbcImpl();
    		User user = dao.findUserByUsernameAndPassword(username, password);
    		//设置响应头信息
    		resp.setContentType("text/html;charset=utf-8");
    		//获取输出流
    		PrintWriter  out = resp.getWriter();
    		if(user == null ) {
    			//登录失败
    			out.println("登录失败!!!!");
    		}else {
    			//登录成功
    			out.println("登录成功!!!!");
    			}
    		out.close();
    

    登录功能实现-页面中错误提示

    涉及的技术知识点

    • 请求重定向
    • 请求转发
    • Jsp页面
    • EL表达式
    • JS简单应用

    请求重定向 redirect

    • Servlet接收到浏览器端请求并处理完成后,给浏览器端一个特殊的响应,这个特殊的响应要求浏览器去请求一个新的资源,整个过程中浏览器端会发出两次请求,且浏览器地址栏会改变为新资源的地址。
    • 重定向的情况下,原Servlet和目标资源之间就不能共享请求域数据了
    • 实现重定向的API
      在这里插入图片描述

    请求转发

    • Servlet接收到浏览器端请求后,进行一定的处理,先不进行响应,而是在服务器端内部“转发”给其他Servlet程序继续处理。在这种情况下浏览器端只发出了一次请求,浏览器地址栏不会发生变化,用户也感知不到请求被转发了。
    • 转发请求的Servlet和目标Servlet共享同一个request对象。
    • 实现转发的API
      在这里插入图片描述

    重定向与转发的区别

    转发 重定向
    浏览器地址栏 不改变 改变
    发送请求次数
    能否共享request对象数据
    目标资源:WEB-INF下的资源 能访问 不能访问
    Request中绑定的数据是否可以传递 不能

    JSP页面

    1. JSP全称Java Server Pages,顾名思义就是运行在java服务器中的页面,也就是在我们JavaWeb中的动态页面,其本质就是一个Servlet。

    2. 其本身是一个动态网页技术标准,它的主要构成有HTML网页代码、Java代码片段、JSP标签几部分组成,后缀是.jsp

    3. 相比于Servlet,JSP更加善于处理显示页面,而Servlet跟擅长处理业务逻辑,两种技术各有专长,所以一般我们会将Servlet和JSP结合使用,Servlet负责业务,JSP负责显示。

    4. 一般情况下, 都是Servlet处理完的数据,转发到JSP,JSP负责显示数据的工作

    5. JSP的基本语法:
      jsp

    6. JSP的脚本元素
      脚本片段是嵌入到JSP中Java代码段,格式以<%开头,%>结尾,两个%号之间就可以编写Java代码了
      jsp

    7. JSP的表达式
      ①JSP表达式用来直接将Java变量输出到页面中,格式以<%=开头,以%>结尾,中间是我们要输出的内容
      jsp

    8. JSP的隐含对象
      ①out(JspWriter):相当于response.getWriter()获取的对象,用于在页面中显示信息。
      ②config(ServletConfig):对应Servlet中的ServletConfig对象。
      ③page(Object):对应当前Servlet对象,实际上就是this。
      ④pageContext(PageContext):当前页面的上下文,也是一个域对象。
      ⑤exception(Throwable):错误页面中异常对象
      ⑥request(HttpServletRequest):HttpServletRequest对象
      ⑦response(HttpServletResponse):HttpServletResponse对象
      ⑧application(ServletContext):ServletContext对象
      ⑨session(HttpSession):HttpSession对象

    9. EL表达式
      ①EL是JSP内置的表达式语言,用以访问页面的上下文以及不同作用域中的对象 ,取得对象属性的值,或执行简单的运算或判断操作。EL在得到某个数据时,会自动进行数据类型的转换。
      ②EL表达式用于代替JSP表达式(<%= %>)在页面中做输出操作。
      ③EL表达式仅仅用来读取数据,而不能对数据进行修改。
      ④使用EL表达式输出数据时,如果有则输出数据,如果为null则什么也不输出。
      ⑤EL表达式的语法:
      EL
      ⑥EL取值的四个域:
      pageScope
      requestScope
      sessionScope
      applicationScope

                         <%=5>3?"大于":"小于" %>
    

    页面中错误提示的功能效果

    在这里插入图片描述

    JavaScript

    1. 在1995年时,由Netscape公司的Brendan Eich,在网景导航者浏览器上首次设计实现而成。Netscape在最初将其脚本语言命名为LiveScript,因为Netscape与Sun合作,网景公司管理层希望它外观看起来像Java,因此取名为JavaScript。
    2. 特性
      ①脚本语言。JavaScript是一种解释型的脚本语言,C、C++、Java等语言先编译后执行, 而JavaScript是在程序的运行过程中逐行进行解释。
      ②基于对象。JavaScript是一种基于对象的脚本语言,它不仅可以创建对象,也能使用现有的对象。
      ③简单。JavaScript语言中采用的是弱类型的变量类型,对使用的数据类型未做出严格的要求,是基于Java基本语句和控制的脚本语言。
      ④动态性。JavaScript是一种采用事件驱动的脚本语言,它不需要经过Web服务器就可以对用户的输入做出响应。
      ⑤跨平台性。JavaScript脚本语言不依赖于操作系统,仅需要浏览器的支持。因此一个JavaScript脚本在编写后可以带到任意机器上使用,前提是机器上的浏览器支 持JavaScript脚本语言,目前JavaScript已被大多数的浏览器所支持。
    3. 编写位置
      ①编写到HTML中
    • onload
    • onclick
    • onblur
    • onfocus
    • onmouseover
    • onmouseout
    1. BOM
      ①Borwser Object Model 浏览器对象模型
      ②浏览器对象模型提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。BOM由多个对象组成,其中代表浏览器窗口的Window对象是BOM的顶层对象,其他对象都是该对象的子对象
      ③常用的对象(window的子对象)
      document history location screen navigator frames
    2. DOM
      ①Document Object Model 文档对象模型
      ②document对象: window对象的一个属性,代表当前HTML文档,包含了整个文档的树形结构。获 取document对象的本质方法是:window.document,而“window.”可以省略。
      ③DOM树
      DOM
      ④元素查询
    功能 API 返回值
    根据id值查询 document.getElementById(“id值”) 一个具体的元素节点
    根据标签名查询 document.getElementsByTagName(“标签名”) 元素节点数组
    根据name属性值查询 document.getElementsByName(“name值”) 元素节点数组

    注册功能实现-异步的表单校验

    涉及的技术知识点

    • Ajax

    Ajax

    1. AJAX 是 Asynchronous JavaScript And XML 的简称。直译为,异步的JS和XML。
    2. AJAX的实际意义是,不发生页面跳转、异步载入内容并改写页面内容的技术。
    3. AJAX也可以简单的理解为通过JS向服务器发送请求。

    异步处理

    1. 同步处理
      AJAX出现之前,我们访问互联网时一般都是同步请求,也就是当我们通过一个页面向服务器发送一个请求时,在服务器响应结束之前,我们的整个页面是不能操作的,也就是直观上来看他是卡主不动的。
      这就带来了非常糟糕的用户体验。首先,同步请求时,用户只能等待服务器的响应,而 不能做任何操作。其次,如果请求时间过长可能会给用户一个卡死的感觉。最后,同步请求的最大缺点就是即使整个页面中只有一小部分内容发生改变我们也要刷新整个页面。
    2. 异步处理
      而异步处理指的是我们在浏览网页的同时,通过AJAX向服务器发送请求,发送请求的过程中我们浏览网页的行为并不会收到任何影响,甚至主观上感知不到在向服务器发送请求。当服务器正常响应请求后,响应信息会直接发送到AJAX中,AJAX可以根据服务器响应的内容做一些操作。
      使用AJAX的异步请求基本上完美的解决了同步请求带来的问题。首先,发送请求时不会影响到用户的正常访问。其次,即使请求时间过长,用户不会有任何感知。最后,AJAX可以根据服务器的响应信息局部的修改页面,而不需要整个页面刷新。

    异步请求对象

    1. XMLHttpRequest对象是AJAX中非常重要的对象,所有的AJAX操作都是基于该对象的。
      XMLHttpRequest对象用来封装请求报文,我们向服务器发送的请求信息全部都需要封装到该对象中。
      这里需要稍微注意一下,XMLHttpRequest对象并没有成为标准,但是现在的主流浏览器都支持该对象,而一些如IE6的老版本浏览器中的创建方式有一些区别,但是问题不大。
    • Xhr对象的获取
      xhr
    • Xhr对象的方法
      ①open(method,url,async)
      open()用于设置请求的基本信息,接收三个参数。
      ①method
      请求的方法:get或post
      接收一个字符串
      ②url
      请求的地址,接收一个字符串
      ③Assync
      发送的请求是否为异步请求,接收一个布尔值。
      true 是异步请求
      false 不是异步请求(同步请求)
      ②send(string)
      send()用于将请求发送给服务器,可以接收一个参数
      ①string参数
      该参数只在发送post请求时需要。
      string参数用于设置请求体
      ③setRequestHeader(header,value)
      用于设置请求头
      ①header参数
      字符串类型,要设置的请求头的名字
      ②value参数
      字符串类型,要设置的请求头的值
    • XMLHttpRequest对象的属性
    1. readyState
      ①描述XMLHttpRequest的状态
      ②一共有五种状态分别对应了五个数字:
      0 :请求尚未初始化,open()尚未被调用
      1 :服务器连接已建立,send()尚未被调用
      2 :请求已接收,服务器尚未响应
      3 :请求已处理,正在接收服务器发送的响应
      4 :请求已处理完毕,且响应已就绪。
      2)status
      ①请求的响应码
      200 响应成功
      404 页面为找到
      500 服务器内部错误
      … … … …
      3)onreadystatechange
      ①该属性需要指向一个函数
      ②该函数会在readyState属性发生改变时被调用
      4)responseText
      ①获得字符串形式的响应数据。
      5)responseXML(用的比较少)
      ①获得 XML 形式的响应数据。
      6)示例代码
      在这里插入图片描述

    在这里插入图片描述

    • 使用JQuery框架来发送异步请求
    1. JQuery是当前比较主流的 JavaScript 库,封装了很多预定义的对象和实现函数,帮助使用者建立有高难度交互的页面,并且兼容大部分主流
      的浏览器.
      JQuery对同样提供了对Ajax的支持,可以更加方便快速的进行Ajax的开发,相关的方法有$.get $.post $.ajax等.
      JQuery的对象的本质就是dom对象的数组/集合

    2. JQuery对象与dom对象的相互转换
      JS转JQuery: var jObj = $(dObj);
      JQuery转JS: var dObj = jObj[0] 或者 var dObj = jObj.get(0)

    3. $.get方法
      在这里插入图片描述

    4. $.post方法
      在这里插入图片描述

    5. $.ajax方法
      jQuery 底层 AJAX 实现。简单易用的高层实现见 $.get, .post.post 等。.ajax() 返回其创建的 XMLHttpRequest 对象。大多数情况下你无需直接操作该函数,除非你需要操作不常用的选项,以获得更多的灵活性。最简单的情况下,$.ajax()可以不带任何参数直接使用。
      $.ajax方法的参数
      在这里插入图片描述
      对于settings请求设置来说,所有选项都是可选的,详见jQuery手册

    6. 具体的示例代码
      在这里插入图片描述

    登录功能实现-登录成功跳转主页面

    涉及的技术知识点

    • Session会话
    • Cookie
    • JSTL标签

    Cookie

    1. HTTP是无状态协议,服务器不能记录浏览器的访问状态,也就是说服务器不能区分中两次请求是否由一个客户端发出。这样的设计严重阻碍的Web程序的设计。如:在我们进行网购时,买了一条裤子,又买了一个手机。由于http协议是无状态的,如果不通过其他手段,服务器是不能知道用户到底买了什么。而Cookie就是解决方案之一。

    2. Cookie实际上就是服务器保存在浏览器上的一段信息。浏览器有了Cookie之后,每次向服务器发送请求时都会同时将该信息发送给服务器,服务器收到请求后,就可以根据该信息处理请求。

    3. Cookie的用途
      网上商城购物车
      用户登录状态的保持

    4. Cookie的限制性
      ①Cookie作为请求或响应报文发送,无形中增加了网络流量。
      ②Cookie是明文传送的安全性差。
      ③各个浏览器对Cookie有限制,使用上有局限

    5. Cookie的具体使用
      ①创建cookie
      在这里插入图片描述
      ②读取cookie
      在这里插入图片描述

    Session

    1. 使用Cookie有一个非常大的局限,就是如果Cookie很多,则无形的增加了客户端与服务端的数据传输量。而且由于浏览器对Cookie数量的限制,注定我们不能再Cookie中保存过多的信息,于是Session出现。
    2. Session的作用就是在服务器端保存一些用户的数据,然后传递给用户一个名字为JSESSIONID的Cookie,这个JESSIONID对应这个服务器中的一个Session对象,通过它就可以获取到保存用户信息的Session。
    3. Session的工作原理
      ①Session的创建时机是在request.getSession()方法第一次被调用时。
      ②Session被创建后,同时还会有一个名为JSESSIONID的Cookie被创建。
      ③这个Cookie的默认时效就是当前会话。
      ④简单来说,Session机制也是依赖于Cookie来实现的
    4. Session的具体使用
      在这里插入图片描述
    5. Session的时效问题
      Session默认有效时间为30分钟,可以在服务器的web.xml配置中修改.
      在这里插入图片描述

    URL重写

    1. 整个会话控制技术体系中,保持JSESSIONID的值主要通过Cookie实现。但Cookie在浏览器端可能会被禁用,所以我们还需要一些备用的技术手段,例如:URL重写。
    2. URL重写其实就是将JSESSIONID的值以固定格式附着在URL地址后面,以实现保持JSESSIONID,进而保持会话状态。这个固定格式是:URL;jsessionid=xxxxxxxxx
    3. 实现方式
      在这里插入图片描述

    具体功能展示

    在这里插入图片描述

    主页面访问权限控制

    涉及的技术知识点

    • 过滤器

    过滤器

    1. 对于WEB应用来说,过滤器是一个驻留在服务器中的WEB组件,他可以截取客户端和WEB资源之间的请求和响应信息。WEB资源可能包括Servlet、JSP、HTML页面等
    2. 当服务器收到特定的请求后,会先将请求交给过滤器,程序员可以在过滤器中对请求信息进行读取修改等操作,然后将请求信息再发送给目标资源。目标资源作出响应后,服务器会再次将响应转交给过滤器,在过滤器中同样可以对响应信息做一些操作,然后再将响应发送给服务器。
    3. 也就是说过滤器可以在WEB资源收到请求之前,浏览器收到响应之前,对请求和响应信息做一些相应的操作。
    4. 在一个WEB应用中可以部署多个过滤器,多个过滤器就组成了一个过滤器链,请求和响应必须在经过多个过滤器后才能到达目标
      在这里插入图片描述

    过滤器的使用

    1. 通过实现Filter接口完成过滤器的开发
      在这里插入图片描述
    2. Filter在web.xml中的配置
      在这里插入图片描述

    主页面访问权限控制要求

    1. 在进入主页面必须进行登录状态的判断,如果未登录状态不允许进入主界面。
    2. 登录状态的判断再过滤器中实现,更为通用,而且可拔插。

    在线人数统计

    涉及的技术知识点

    • 监听器

    监听器

    1. Listener用于监听JavaWeb程序中的事件。
    2. 例如:ServletContext、HttpSession、ServletRequest的创建、修改和删除。
    3. 监听器的类型分为
      ①生命周期
      ②数据绑定
      在这里插入图片描述

    在线人数统计功能展示

    在这里插入图片描述

    xml

    xml简介

    1. XML–可扩展标记语言eXtensible Markup Language
    2. 由W3C组织发布,目前推荐遵守的是W3C组织于2000年发布的XML1.0规范
    3. XML的使命,就是以一个统一的格式,组织有关系的数据,为不同平台下的应用程序服务
    4. XML用来传输和存储数据,HTML用来显示数据
    5. XML没有预定义标签,均为自定义标签

    xml用途

    1. 配置文件
      JavaWeb中的web.xml
      C3P0中的c3p0-config.xml
    2. 数据交换格式
      Ajax
      WebService
    3. 数据存储
      保存关系型数据

    在这里插入图片描述

    xml基本语法

    1. XML文档组成
      ①XML声明
      version属性指定XML版本,固定值是1.0
      encoding指定的字符集,是告诉解析器使用什么字符集进行解码,而编码是由文本 编辑器决定的
      ②CDATA区
      当XML文档中需要写一些程序代码、SQL语句或其他不希望XML解析器进行解析 的内容时,就可以写在CDATA区中
      XML解析器会将CDATA区中的内容原封不动的输出
      CDATA区的定义格式:<![CDATA[…]]>
    2. 语法规则
      ①XML声明要么不写,要写就写在第一行,并且前面没有任何其他字符
      ②只能有一个根标签
      ③标签必须正确结束
      ④标签不能交叉嵌
      ⑤严格区分大小写
      ⑥属性必须有值,且必须加引号
      ⑦标签不能以数字开头
      ⑧注释不能嵌套

    xml解析

    1. XML解析是指通过解析器读取XML文档,解释语法,并将文档转化成对象
    2. 常用的解析方式
      DOM(Document Object Model)
      SAX(Simple API for XML)
    3. DOM 和SAX解析的对比
      在这里插入图片描述
    4. Dom4j解析示例
      解析
    //1.创建解析器对象
    SAXReader saxReader = new SAXReader();
    //2.解析xml文件获取document对象
    Document document = saxReader.read("students.xml");
    //3.得到根元素
    Element root = document.getRootElement();
    

    JSON

    JSON 简介

    1. AJAX一开始使用的时XML的数据格式,XML的数据格式非常简单清晰,容易编写,但是由于XML中包含了过多的标签,以及十分复杂的结构,解析起来也相对复杂,所以目前来讲,AJAX中已经几乎不使用XML来发送数据了。取而代之的是一项新的技术JSON。
    2. JSON是JavaScript Object Notation 的缩写,是JS提供的一种数据交换格式。
    3. JSON对象本质上就是一个JS对象,但是这个对象比较特殊,它可以直接转换为字符串,在不同语言中进行传递,通过工具又可以转换为其他语言中的对象。
    4. 例,有如下一个JSON对象:
      ①{“name”:”sunwukong” , ”age”:18 , ”address”:”beijing” }
      ②这个对象中有三个属性name、age和address
      ③如果将该对象使用单引号引起了,那么他就变成了一个字符串
      ④‘{“name”:”sunwukong” , ”age”:18 , ”address”:”beijing” }’
      ⑤变成字符串后有一个好处,就是可以在不同语言之间传递。
      ⑥比如,将JSON作为一个字符串发送给Servlet,在Java中就可以把JSON字符串转换为一个Java对象。

    JSON通过6种数据类型来表示

    1. 字符串
    • 例子:”字符串”
    • 注意:不能使用单引号
    1. 数字:
    • 例子:123.4
    1. 布尔值:
    • 例子:true、false
    1. null值:
    • 例子:null
    1. 对象
    • 例子:{“name”:”sunwukong”, ”age”:18}
      6.数组
    • 例子:[1,”str”,true]

    在JS中操作JSON

    1. 创建JSON对象
    • var json = {“name1”:”value1”,”name2”:”value2” , “name3”:[1,”str”,true]};
    • var json = [{“name1”:”value1”},{“name2”:”value2”}];
    1. JSON对象转换为JSON字符串
    • JSON.stringify(JSON对象)
    1. JSON字符串转换为JSON对象
    • JSON.parse(JSON字符串)

    在Java中操作JSON

    1. 在Java中可以从文件中读取JSON字符串,也可以是客户端发送的JSON字符串,所以第一个问题,我们先来看如何将一个JSON字符串转换成一个Java对象。
    2. 首先解析JSON字符串我们需要导入第三方的工具,目前主流的解析JSON的工具大概有三种json-lib、jackson、gson。三种解析工具相比较json-lib的使用复杂,且效率较差。而Jackson和gson解析效率较高。使用简单,这里我们以gson为例讲解。
    3. Gson是Google公司出品的解析JSON工具,使用简单,解析性能好。
    4. Gson中解析JSON的核心是Gson的类,解析操作都是通过该类实例进行。
    5. JSON字符串转换为对象
    String json = "{\"name\":\"张三\",\"age\":18}";
    Gson gson = new Gson();
    //转换为集合
    Map<String,Object> stuMap = gson.fromJson(json, Map.class);
    //如果编写了相应的类也可以转换为指定对象
    Student fromJson = gson.fromJson(json, Student.class);
    
    1. 对象转换为JSON字符串
    Student stu = new Student("李四", 23);
    Gson gson = new Gson();
    //{"name":"李四","age":23}
    String json = gson.toJson(stu);
    		
    Map<String , Object> map = new HashMap<String, Object>();
    map.put("name", "孙悟空");
    map.put("age", 30);
    //{"age":30,"name":"孙悟空"}
    String json2 = gson.toJson(map);
    		
    List<Student> list = new ArrayList<Student>();
    list.add(new Student("八戒", 18));
    list.add(new Student("沙僧", 28));
    list.add(new Student("唐僧", 38));
    //[{"name":"八戒","age":18},{"name":"沙僧","age":28},
    {"name":"唐僧","age":38}]
    String json3 = gson.toJson(list);		
         // 如果将一个数组格式的json字符串转换成java对象需要用到
         //Gson提供的一个匿名内部类: TypeToken
    	TypeToken tk= new TypeToken<List<User>>(){};
    	List<User> list2 = gson.fromJson(json,tk.getType());
    	System.out.println(list2.get(0));
    

    JQuery 异步请求返回JSON数据

    1. Servlet 返回json数据
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		
    		List<Employee> emps = new EmployeeDaoJdbcImpl().getAllEmps();
    		Gson gson = new Gson();
    		String jsonStr = gson.toJson(emps);
    		response.setContentType("text/html;charset=utf-8");
    		PrintWriter out = response.getWriter();
    		out.println(jsonStr);
    		out.close();
    }
    
    1. 页面中处理 json数据
    function getJsonStr(){
    		//通过JQuery发送异步请求, 将所有的员工信息通过json的格式返回
     $.ajax({
    	url:"getEmpsJsonStr",
    	type:"post",
    	dataType:"json",
    	success:function(data){  // 会直接将后台返回的json字符串转换成js对象
    		var str = "<tr><th>Id</th><th>LastName</th><th>Email</th><th>Gender</th></tr>";
    		for(var i= 0 ;i <data.length;i++){
    			var emp = data[i];
    			str+="<tr align='center'><td>"
                     +emp.id+
                     "</td><td>"
                     +emp.lastName+
                     "</td><td>"
                     +emp.email+
                     "</td><td>"
                     +emp.gender+
                     "</td></tr>"	
    		}	
    				$("#tb").html(str);
    			}
    		});
    	}
    
    <body>
    	<input type="button" value="getJsonStr" onclick="getJsonStr();"/>
    	<table id="tb" border="1px"  align="center" width="60%" cellspacing="0px" >	
    	</table>
    </body>
    
    OctoberMon 08Mon 15Mon 22Mon 29Mon 05Mon 12Mon 19Mon 26已完成 进行中 计划一 计划二 现有任务大数据学习计划
    展开全文
  • javaweb项目教程

    万次阅读 2018-08-21 23:39:04
    手把手搭建一个完整的javaweb项目 原文:https://blog.csdn.net/qq_23994787/article/details/73612870 本案例使用Servlet+jsp制作,用MyEclipse和Mysql数据库进行搭建,详细介绍了搭建过程及知识点。   ...

    手把手搭建一个完整的javaweb项目

    原文:https://blog.csdn.net/qq_23994787/article/details/73612870

    本案例使用Servlet+jsp制作,用MyEclipse和Mysql数据库进行搭建,详细介绍了搭建过程及知识点。

     

    下载地址:http://download.csdn.net/detail/qq_23994787/9904842  点击下载

    主要功能有:

    1.用户注册

    2.用户登录

    3.用户列表展示

    4.用户信息修改

    5.用户信息删除

     

    涉及到的知识点有:   

    1.JDBC

    2.Servlet

    3.过滤器

    4..EL与JSTL表达式

     

    1.首先打开mysql数据库 新建一个数据库test,然后生成对应的表结构

     

    
     
    1. CREATE TABLE `user` (

    2. `id` int(11) NOT NULL auto_increment,

    3. `name` varchar(255) NOT NULL,

    4. `pwd` varchar(255) NOT NULL,

    5. `sex` varchar(255) NOT NULL,

    6. `home` varchar(255) NOT NULL,

    7. `info` varchar(255) NOT NULL,

    8. PRIMARY KEY (`id`)

    9. ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

    10.  
    11.  
    12. INSERT INTO `user` VALUES ('3', '123', '123', '123', '123', '123');

    13. INSERT INTO `user` VALUES ('4', '123123', '123123', '男', '北京', '123123');

     

    这里使用到了navicat for mysql    这是一种mysql的图形界面化工具,后期可以非常方便的操作数据库。

     

    需要的童鞋 给你们个连接     http://download.csdn.net/download/qq_23994787/10168988

    2.然后打开MyEclipse新建一个web项目

    3.在webroot下的WEB-INF下的lib中导入mysql的驱动jar包

    4.建立对应的包结构 
    com.filter   //过滤器 解决中文字符集乱码
    com.util     //数据库连接工具类
    com.entity   //实体类
    com.dao      //数据操作类
    com.servlet   //servlet类

    5.在filter下新建一个EncodingFilter用来解决中文字符集乱码,它需要实现Filter接口,并重写doFilter函数

     

    
     
    1. package com.filter;

    2.  
    3. import java.io.IOException;

    4.  
    5. import javax.servlet.Filter;

    6. import javax.servlet.FilterChain;

    7. import javax.servlet.FilterConfig;

    8. import javax.servlet.ServletException;

    9. import javax.servlet.ServletRequest;

    10. import javax.servlet.ServletResponse;

    11.  
    12. public class EncodingFilter implements Filter{

    13. public EncodingFilter(){

    14. System.out.println("过滤器构造");

    15. }

    16. public void destroy() {

    17. System.out.println("过滤器销毁");

    18. }

    19. public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {

    20. request.setCharacterEncoding("utf-8"); //将编码改为utf-8

    21. response.setContentType("text/html;charset=utf-8");

    22. chain.doFilter(request, response);

    23. }

    24.  
    25. public void init(FilterConfig arg0) throws ServletException {

    26. System.out.println("过滤器初始化");

    27. }

    28.  
    29. }

     


    6.到web.xml下进行对EncodingFilter相应的配置

     

     

     

    
     
    1. <?xml version="1.0" encoding="UTF-8"?>

    2. <web-app version="2.5"

    3. xmlns="http://java.sun.com/xml/ns/javaee"

    4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    5. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

    6. http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    7. <display-name></display-name>

    8.  
    9. <filter>

    10. <filter-name>EncodingFilter</filter-name>

    11. <filter-class>com.filter.EncodingFilter</filter-class><!--全路径 从根包开始一直到类名-->

    12. </filter>

    13. <filter-mapping>

    14. <filter-name>EncodingFilter</filter-name>

    15. <url-pattern>/*</url-pattern> <!--*即为过滤所有-->

    16. </filter-mapping>

    17.  
    18.  
    19. <welcome-file-list>

    20. <welcome-file>denglu.jsp</welcome-file>

    21. </welcome-file-list>

    22. </web-app>

     


    7.在util下新建一个DBconn类用来处理对数据库的连接操作(用户名或密码按照自己的数据库更改)

     

     

     

    
     
    1. package com.util;

    2.  
    3. import java.sql.*;

    4.  
    5. public class DBconn {

    6. static String url = "jdbc:mysql://localhost:3306/test?useunicuee=true& characterEncoding=utf8";

    7. static String username = "root";

    8. static String password = "root";

    9. static Connection conn = null;

    10. static ResultSet rs = null;

    11. static PreparedStatement ps =null;

    12. public static void init(){

    13. try {

    14. Class.forName("com.mysql.jdbc.Driver");

    15. conn = DriverManager.getConnection(url,username,password);

    16. } catch (Exception e) {

    17. System.out.println("init [SQL驱动程序初始化失败!]");

    18. e.printStackTrace();

    19. }

    20. }

    21. public static int addUpdDel(String sql){

    22. int i = 0;

    23. try {

    24. PreparedStatement ps = conn.prepareStatement(sql);

    25. i = ps.executeUpdate();

    26. } catch (SQLException e) {

    27. System.out.println("sql数据库增删改异常");

    28. e.printStackTrace();

    29. }

    30.  
    31. return i;

    32. }

    33. public static ResultSet selectSql(String sql){

    34. try {

    35. ps = conn.prepareStatement(sql);

    36. rs = ps.executeQuery(sql);

    37. } catch (SQLException e) {

    38. System.out.println("sql数据库查询异常");

    39. e.printStackTrace();

    40. }

    41. return rs;

    42. }

    43. public static void closeConn(){

    44. try {

    45. conn.close();

    46. } catch (SQLException e) {

    47. System.out.println("sql数据库关闭异常");

    48. e.printStackTrace();

    49. }

    50. }

    51. }

     


    8.在entity下新建一个User实体类(实体即抽象出来的用户对象,对应数据库中的user表,表中每个字段在实体中为一个属性,也可以理解为一个User对象对应数据库中的user表一条记录)

     

     

     

    
     
    1. package com.entity;

    2.  
    3. public class User {

    4. private int id;

    5. private String name;

    6. private String pwd;

    7. private String sex;

    8. private String home;

    9. private String info;

    10. public int getId() {

    11. return id;

    12. }

    13. public void setId(int id) {

    14. this.id = id;

    15. }

    16. public String getName() {

    17. return name;

    18. }

    19. public void setName(String name) {

    20. this.name = name;

    21. }

    22. public String getPwd() {

    23. return pwd;

    24. }

    25. public void setPwd(String pwd) {

    26. this.pwd = pwd;

    27. }

    28. public String getSex() {

    29. return sex;

    30. }

    31. public void setSex(String sex) {

    32. this.sex = sex;

    33. }

    34. public String getHome() {

    35. return home;

    36. }

    37. public void setHome(String home) {

    38. this.home = home;

    39. }

    40. public String getInfo() {

    41. return info;

    42. }

    43. public void setInfo(String info) {

    44. this.info = info;

    45. }

    46.  
    47. }

     


    9.在dao下新建一个UserDao接口  以及对应的方法实现类(使用接口类是为了规范开发)

     

     

    UserDao.java

     

    
     
    1. package com.dao;

    2.  
    3. import java.util.List;

    4.  
    5. import com.entity.User;

    6.  
    7. public interface UserDao {

    8. public boolean login(String name,String pwd);//登录

    9. public boolean register(User user);//注册

    10. public List<User> getUserAll();//返回用户信息集合

    11. public boolean delete(int id) ;//根据id删除用户

    12. public boolean update(int id,String name, String pwd,String sex, String home,String info) ;//更新用户信息

    13. }

     

    新建UserDaoImpl.java     实现UserDao接口,及未实现的方法     (SQL语句建议在mysql中测试以下,没有问题然后在拿到实现类中使用,可以避免无必要的麻烦)

    本例子SQL使用字符串拼接的方式,其实还有一种预加载的方式,有兴趣的童鞋可以参考我的博客,了解预加载的方式处理SQL语句与字符串拼接方式的区别。

    
     
    1. package com.dao;

    2.  
    3. import java.sql.ResultSet;

    4. import java.sql.SQLException;

    5. import java.util.ArrayList;

    6. import java.util.List;

    7.  
    8. import com.entity.User;

    9. import com.util.DBconn;

    10.  
    11. public class UserDaoImpl implements UserDao{

    12.  
    13. public boolean register(User user) {

    14. boolean flag = false;

    15. DBconn.init();

    16. int i =DBconn.addUpdDel("insert into user(name,pwd,sex,home,info) " +

    17. "values('"+user.getName()+"','"+user.getPwd()+"','"+user.getSex()+"','"+user.getHome()+"','"+user.getInfo()+"')");

    18. if(i>0){

    19. flag = true;

    20. }

    21. DBconn.closeConn();

    22. return flag;

    23. }

    24. public boolean login(String name, String pwd) {

    25. boolean flag = false;

    26. try {

    27. DBconn.init();

    28. ResultSet rs = DBconn.selectSql("select * from user where name='"+name+"' and pwd='"+pwd+"'");

    29. while(rs.next()){

    30. if(rs.getString("name").equals(name) && rs.getString("pwd").equals(pwd)){

    31. flag = true;

    32. }

    33. }

    34. DBconn.closeConn();

    35. } catch (SQLException e) {

    36. e.printStackTrace();

    37. }

    38. return flag;

    39. }

    40. public List<User> getUserAll() {

    41. List<User> list = new ArrayList<User>();

    42. try {

    43. DBconn.init();

    44. ResultSet rs = DBconn.selectSql("select * from user");

    45. while(rs.next()){

    46. User user = new User();

    47. user.setId(rs.getInt("id"));

    48. user.setName(rs.getString("name"));

    49. user.setPwd(rs.getString("pwd"));

    50. user.setSex(rs.getString("sex"));

    51. user.setHome(rs.getString("home"));

    52. user.setInfo(rs.getString("info"));

    53. list.add(user);

    54. }

    55. DBconn.closeConn();

    56. return list;

    57. } catch (SQLException e) {

    58. e.printStackTrace();

    59. }

    60. return null;

    61. }

    62. public boolean update(int id,String name, String pwd,String sex, String home,String info) {

    63. boolean flag = false;

    64. DBconn.init();

    65. String sql ="update user set name ='"+name

    66. +"' , pwd ='"+pwd

    67. +"' , sex ='"+sex

    68. +"' , home ='"+home

    69. +"' , info ='"+info+"' where id = "+id;

    70. int i =DBconn.addUpdDel(sql);

    71. if(i>0){

    72. flag = true;

    73. }

    74. DBconn.closeConn();

    75. return flag;

    76. }

    77. public boolean delete(int id) {

    78. boolean flag = false;

    79. DBconn.init();

    80. String sql = "delete from user where id="+id;

    81. int i =DBconn.addUpdDel(sql);

    82. if(i>0){

    83. flag = true;

    84. }

    85. DBconn.closeConn();

    86. return flag;

    87. }

    88.  
    89. }

     

     

     

    10.在servlet下创建DengluServlet用来实现对用户登录的操作(Servlet有两种方式创建,一种手工创建。另一种程序自动生成。前者自己创建java类,实现Servlet具体内容,然后需要去WEB_INF下的web.xml去配置servlet  . 而后者则直接由程序替我们配置好了Servlet)本例子使用第二种方式生成Servlet

     

     

     

    DengluServlet.java

     

    
     
    1. package com.servlet;

    2.  
    3. import java.io.IOException;

    4. import java.io.PrintWriter;

    5.  
    6. import javax.servlet.ServletException;

    7. import javax.servlet.http.HttpServlet;

    8. import javax.servlet.http.HttpServletRequest;

    9. import javax.servlet.http.HttpServletResponse;

    10.  
    11. import com.dao.UserDao;

    12. import com.dao.UserDaoImpl;

    13.  
    14. public class DengluServlet extends HttpServlet { //需要继承HttpServlet 并重写doGet doPost方法

    15. public void doGet(HttpServletRequest request, HttpServletResponse response)

    16. throws ServletException, IOException {

    17. doPost(request, response); //将信息使用doPost方法执行 对应jsp页面中的form表单中的method

    18. }

    19. public void doPost(HttpServletRequest request, HttpServletResponse response)

    20. throws ServletException, IOException {

    21.  
    22. String name = request.getParameter("name"); //得到jsp页面传过来的参数

    23. String pwd = request.getParameter("pwd");

    24.  
    25. UserDao ud = new UserDaoImpl();

    26.  
    27. if(ud.login(name, pwd)){

    28. request.setAttribute("xiaoxi", "欢迎用户"+name); //向request域中放置信息

    29. request.getRequestDispatcher("/success.jsp").forward(request, response);//转发到成功页面

    30. }else{

    31. response.sendRedirect("index.jsp"); //重定向到首页

    32. }

    33. }

    34.  
    35. }

     

    有两点要注意的地方:

    一:getParameter与getAttribute两者的区别

    request.setAttribute("xiaoxi", "欢迎用户"+name);//向request域中放置信息 ( 键值对的形式)  名字为xiaoxi  内容为"欢迎用户"+name

    request.getAttribute("xiaoxi");//得到request域中放置名字为xiaoxi的信息

    request.getParameter("name");//得到request域的参数信息(得到jsp页面传过来的参数)

    getAttribute表示从request范围取得设置的属性,必须要先setAttribute设置属性,才能通过getAttribute来取得,设置与取得的为Object对象类型 。

    getParameter表示接收参数,参数为页面提交的参数,包括:表单提交的参数、URL重写(就是xxx?id=1中的id)传的参数等,因此这个并没有设置参数的方法(没有setParameter),而且接收参数返回的不是Object,而是String类型

    二:转发与重定向的区别

    (1).重定向的执行过程:Web服务器向浏览器发送一个http响应--》浏览器接受此响应后再发送一个新的http请求到服务器--》服务器根据此请求寻找资源并发送给浏览器。它可以重定向到任意URL,不能共享request范围内的数据。
    (2).重定向是在客户端发挥作用,通过新的地址实现页面转向。
    (3).重定向是通过浏览器重新请求地址,在地址栏中可以显示转向后的地址。
    (4).转发过程:Web服务器调用内部方法在容器内部完成请求和转发动作--》将目标资源发送给浏览器,它只能在同一个Web应用中使用,可以共享request范围内的数据。
    (5).转发是在服务器端发挥作用,通过forward()方法将提交信息在多个页面间进行传递。
    (6).转发是在服务器内部控制权的转移,客户端浏览器的地址栏不会显示出转向后的地址。

     

    11.在servlet下创建一个ZhuceServlet用来实现用户注册的操作

     

    ZhuceServlet.java

     

    
     
    1. package com.servlet;

    2.  
    3. import java.io.IOException;

    4. import java.io.PrintWriter;

    5.  
    6. import javax.servlet.ServletException;

    7. import javax.servlet.http.HttpServlet;

    8. import javax.servlet.http.HttpServletRequest;

    9. import javax.servlet.http.HttpServletResponse;

    10. import com.dao.UserDao;

    11. import com.dao.UserDaoImpl;

    12. import com.entity.User;

    13.  
    14. public class ZhuceServlet extends HttpServlet {

    15. public void doGet(HttpServletRequest request, HttpServletResponse response)

    16. throws ServletException, IOException {

    17. doPost(request, response);

    18. }

    19. public void doPost(HttpServletRequest request, HttpServletResponse response)

    20. throws ServletException, IOException {

    21.  
    22. String name = request.getParameter("name"); //获取jsp页面传过来的参数

    23. String pwd = request.getParameter("pwd");

    24. String sex = request.getParameter("sex");

    25. String home = request.getParameter("home");

    26. String info = request.getParameter("info");

    27.  
    28. User user = new User(); //实例化一个对象,组装属性

    29. user.setName(name);

    30. user.setPwd(pwd);

    31. user.setSex(sex);

    32. user.setHome(home);

    33. user.setInfo(info);

    34.  
    35. UserDao ud = new UserDaoImpl();

    36.  
    37. if(ud.register(user)){

    38. request.setAttribute("username", name); //向request域中放置参数

    39. //request.setAttribute("xiaoxi", "注册成功");

    40. request.getRequestDispatcher("/denglu.jsp").forward(request, response); //转发到登录页面

    41. }else{

    42.  
    43. response.sendRedirect("index.jsp");//重定向到首页

    44. }

    45. }

    46. }

     


    12.在servlet下创建SearchallServlet用来返回数据库中所有用户信息

     

     

    Searchall.java

     

    
     
    1. package com.servlet;

    2.  
    3. import java.io.IOException;

    4. import java.io.PrintWriter;

    5. import java.util.List;

    6.  
    7. import javax.servlet.ServletException;

    8. import javax.servlet.http.HttpServlet;

    9. import javax.servlet.http.HttpServletRequest;

    10. import javax.servlet.http.HttpServletResponse;

    11.  
    12. import com.dao.UserDao;

    13. import com.dao.UserDaoImpl;

    14. import com.entity.User;

    15.  
    16. public class Searchall extends HttpServlet {

    17. public void doGet(HttpServletRequest request, HttpServletResponse response)

    18. throws ServletException, IOException {

    19. doPost(request, response);

    20. }

    21. public void doPost(HttpServletRequest request, HttpServletResponse response)

    22. throws ServletException, IOException {

    23.  
    24. UserDao ud = new UserDaoImpl();

    25. List<User> userAll = ud.getUserAll();

    26. request.setAttribute("userAll", userAll);

    27. request.getRequestDispatcher("/showall.jsp").forward(request, response);

    28. }

    29. }

     


    13.在servlet下创建DeleteServlet用来删除用户操作

     

     

    DeleteServlet.java

     

    
     
    1. package com.servlet;

    2.  
    3. import java.io.IOException;

    4. import java.io.PrintWriter;

    5.  
    6. import javax.servlet.ServletException;

    7. import javax.servlet.http.HttpServlet;

    8. import javax.servlet.http.HttpServletRequest;

    9. import javax.servlet.http.HttpServletResponse;

    10.  
    11. import com.dao.UserDao;

    12. import com.dao.UserDaoImpl;

    13.  
    14. public class DeleteServlet extends HttpServlet {

    15. public void doGet(HttpServletRequest request, HttpServletResponse response)

    16. throws ServletException, IOException {

    17. doPost(request, response);

    18. }

    19. public void doPost(HttpServletRequest request, HttpServletResponse response)

    20. throws ServletException, IOException {

    21.  
    22. String id = request.getParameter("id");

    23. int userId = Integer.parseInt(id);

    24.  
    25. UserDao ud = new UserDaoImpl();

    26.  
    27. if(ud.delete(userId)){

    28. request.setAttribute("xiaoxi", "删除成功");

    29. request.getRequestDispatcher("/Searchall").forward(request, response);

    30. }else{

    31. response.sendRedirect("index.jsp");

    32. }

    33. }

    34.  
    35. }

     


    14.在servlet下创建UpdateServlet操作用来更新用户信息

     

     

    UpdateServlet.java

     

    
     
    1. package com.servlet;

    2.  
    3. import java.io.IOException;

    4. import java.io.PrintWriter;

    5.  
    6. import javax.servlet.ServletException;

    7. import javax.servlet.http.HttpServlet;

    8. import javax.servlet.http.HttpServletRequest;

    9. import javax.servlet.http.HttpServletResponse;

    10.  
    11. import com.dao.UserDao;

    12. import com.dao.UserDaoImpl;

    13. import com.entity.User;

    14.  
    15. public class UpdateServlet extends HttpServlet {

    16.  
    17. public void doGet(HttpServletRequest request, HttpServletResponse response)

    18. throws ServletException, IOException {

    19. doPost(request, response);

    20. }

    21. public void doPost(HttpServletRequest request, HttpServletResponse response)

    22. throws ServletException, IOException {

    23.  
    24. String id = request.getParameter("id");

    25. int userId = Integer.parseInt(id);

    26.  
    27. String name = request.getParameter("name");

    28. String pwd = request.getParameter("pwd");

    29. String sex = request.getParameter("sex");

    30. String home = request.getParameter("home");

    31. String info = request.getParameter("info");

    32.  
    33. System.out.println("------------------------------------"+userId);

    34.  
    35. UserDao ud = new UserDaoImpl();

    36.  
    37. if(ud.update(userId, name, pwd, sex, home, info)){

    38. request.setAttribute("xiaoxi", "更新成功");

    39. request.getRequestDispatcher("/Searchall").forward(request, response);

    40. }else{

    41. response.sendRedirect("index.jsp");

    42. }

    43. }

    44. }

    45.  


    15.配置servlet       如果非手打而用MyEclipse生成则不用配置  附完整web.xml

     

     

    
     
    1. <?xml version="1.0" encoding="UTF-8"?>

    2. <web-app version="2.5"

    3. xmlns="http://java.sun.com/xml/ns/javaee"

    4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    5. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

    6. http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    7. <display-name></display-name>

    8.  
    9. <filter><!--过滤器配置-->

    10. <filter-name>EncodingFilter</filter-name>

    11. <filter-class>com.filter.EncodingFilter</filter-class>

    12. </filter>

    13. <filter-mapping>

    14. <filter-name>EncodingFilter</filter-name>

    15. <url-pattern>/*</url-pattern>

    16. </filter-mapping>

    17.  
    18.  
    19.  
    20. <servlet><!--servlet类路径配置-->

    21. <servlet-name>DengluServlet</servlet-name>

    22. <servlet-class>com.servlet.DengluServlet</servlet-class>

    23. </servlet>

    24. <servlet>

    25. <servlet-name>ZhuceServlet</servlet-name>

    26. <servlet-class>com.servlet.ZhuceServlet</servlet-class>

    27. </servlet>

    28. <servlet>

    29. <servlet-name>Searchall</servlet-name>

    30. <servlet-class>com.servlet.Searchall</servlet-class>

    31. </servlet>

    32. <servlet>

    33. <servlet-name>DeleteServlet</servlet-name>

    34. <servlet-class>com.servlet.DeleteServlet</servlet-class>

    35. </servlet>

    36. <servlet>

    37. <servlet-name>UpdateServlet</servlet-name>

    38. <servlet-class>com.servlet.UpdateServlet</servlet-class>

    39. </servlet>

    40.  
    41.  
    42.  
    43. <servlet-mapping><!--servlet类映射配置-->

    44. <servlet-name>DengluServlet</servlet-name>

    45. <url-pattern>/DengluServlet</url-pattern>

    46. </servlet-mapping>

    47. <servlet-mapping>

    48. <servlet-name>ZhuceServlet</servlet-name>

    49. <url-pattern>/ZhuceServlet</url-pattern>

    50. </servlet-mapping>

    51. <servlet-mapping>

    52. <servlet-name>Searchall</servlet-name>

    53. <url-pattern>/Searchall</url-pattern>

    54. </servlet-mapping>

    55. <servlet-mapping>

    56. <servlet-name>DeleteServlet</servlet-name>

    57. <url-pattern>/DeleteServlet</url-pattern>

    58. </servlet-mapping>

    59. <servlet-mapping>

    60. <servlet-name>UpdateServlet</servlet-name>

    61. <url-pattern>/UpdateServlet</url-pattern>

    62. </servlet-mapping>

    63.  
    64.  
    65.  
    66. <welcome-file-list><!--默认首页地址-->

    67. <welcome-file>denglu.jsp</welcome-file>

    68. </welcome-file-list>

    69. </web-app>


    16.新建jsp页面

     

    denglu.jsp 用户登录页面      默认页面进入项目后  先进入该页面(web.xml中配置)    

    form表单中需要注意的是<form action="DengluServlet"  method="post">

    其中action即为要跳转的servlet路径(即在web.xml中配置的servlet-mapping   :<url-pattern>/DengluServlet</url-pattern>   ,)写  /  后的内容。

    method="post"为传递值得方法类型有两种,第一种get,第二种post。网上介绍这两种的区别有很多,阐述的又是百家争鸣。而我觉得那个方便就用那个,一般使用post传递,可避免乱码。

    另一个需要注意的是   用户名:<input type="text" name="name" value="">  input标签  一定要起个名字  如name="name"  

    起名的作用就是让后台通过request.getParterment("name");来取值

     

    
     
    1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

    2. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    3. <html>

    4. <head>

    5. <title>登录注册页面</title>

    6. </head>

    7. <body >

    8. <form action="DengluServlet" method="post" style="padding-top:-700px;">

    9. 用户名:<input type="text" name="name"value=""><br><br>

    10. 密码: <input type="password" name="pwd"value=""><br><br>

    11. <input type="submit"value="登录"name="denglu"><input type="reset"value="重置"><br>

    12. </form>

    13. <form action="zhuce.jsp">

    14. <input type="submit"value="新用户注册">

    15. </form>

    16.  
    17. </body>

    18. </html>


    zhuce.jsp  用户注册页面

     

     

    
     
    1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

    2. <%

    3. String path = request.getContextPath();

    4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

    5. %>

    6. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    7. <html>

    8. <head>

    9. <title>My JSP 'BB.jsp' starting page</title>

    10. </head>

    11. <body >

    12. <form action="ZhuceServlet"method="post" style="padding-top:-700px;">

    13. 输入用户名:<input name="name" type="text"><br><br>

    14. 输入密码:<input name="pwd" type="password"><br><br>

    15. 选择性别:<input type="radio"name="sex"value="男"checked>男

    16. <input type="radio"name="sex"value="女">女<br><br>

    17. 选择家乡:

    18. <select name="home">

    19. <option value="上海">上海</option>

    20. <option value="北京" selected>北京</option>

    21. <option value="纽约">纽约</option>

    22. </select><br>

    23. 填写个人信息:<br>

    24. <textarea name="info" row="5"cols="30"></textarea><br>

    25. <input type="reset"value="重置"><input type="submit"value="注册">

    26. </form>

    27. </body>

    28. </html>

    29.  

     
    index.jsp  失败页面

     

     

    
     
    1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

    2. <%

    3. String path = request.getContextPath();

    4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

    5. %>

    6. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    7. <html>

    8. <head>

    9. <title>My JSP 'index.jsp' starting page</title>

    10. </head>

    11. <body>

    12. <h1>失敗</h1>

    13. </body>

    14. </html>

    15.  

     

    success.jsp  成功页面

     

     

    ${xiaoxi}为EL表达式  获取request域中的键名为xiaoxi的值

    
     
    1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

    2. <%

    3. String path = request.getContextPath();

    4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

    5. %>

    6.  
    7. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    8. <html>

    9. <head>

    10. <title>My JSP 'success.jsp' starting page</title>

    11. </head>

    12. <body>

    13. ${xiaoxi} <br>

    14. <a href="Searchall">查看所有用户</a>

    15. </body>

    16. </html>

    showall.jsp   展现所有用户页面

    页面使用的到JSTL表达式 即c标签。使用c标签需要引入头文件<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 。

    需要注意的的是El标签配合JSTl标签的使用,<c:forEach var="U" items="${userAll}"  >   例子foeEach标签的遍历内容即为EL表达式获取的${userAll}

    而且当指定别名后var="U"  ,别名可以随便起,为了方便一般是小写类名命名。  

    C标签内遍历的属性也是需要用${  }获取。此时别名U即为当前集合中的User对象,想得到属性只需要用 ${ U.属性名 }     即可

    
     
    1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

    2. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

    3. <%

    4. String path = request.getContextPath();

    5. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

    6. %>

    7.  
    8. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    9. <html>

    10. <head>

    11. <base href="<%=basePath%>">

    12. <title>所有用户页面</title>

    13. </head>

    14.  
    15. <body>

    16. <h1>${xiaoxi}</h1>

    17. <table width="600" border="1" cellpadding="0" >

    18. <tr>

    19. <th>ID</th>

    20. <th>姓名</th>

    21. <th>性别</th>

    22. <th>密码</th>

    23. <th>家乡</th>

    24. <th>备注</th>

    25. <th>操作</th>

    26. </tr>

    27. <c:forEach var="U" items="${userAll}" >

    28. <form action="UpdateServlet" method="post">

    29. <tr>

    30. <td><input type="text" value="${U.id}" name="id" ></td>

    31. <td><input type="text" value="${U.name}" name="name"></td>

    32. <td><input type="text" value="${U.sex}" name="sex"></td>

    33. <td><input type="text" value="${U.pwd}" name="pwd"></td>

    34. <td><input type="text" value="${U.home}" name="home"></td>

    35. <td><input type="text" value="${U.info}" name="info"></td>

    36. <td><a href="DeleteServlet?id=${U.id}">删除</a> <input type="submit" value="更新"/></td>

    37. </tr>

    38. </form>

    39. </c:forEach>

    40. </table>

    41. </body>

    42. </html>

    43.  

     

     

    项目结构

    最后要说的话

    1.编程不是看会的,是敲会的。只要敲敲敲,才可以深刻的记忆,当然这只能称之为会用,之后深入了解其实现原理才能将其吸收融会贯通。

    2.要养成良好的代码习惯,整洁干净,命名规范,以及详细的注释。这对帮助你成长都大有裨益。

    3.要阅读大牛写的代码,一个人的力量终究是有限的,经常阅读高质量的源码,无形之中就会改变我们的思路,就好比自己琢磨武功,与拥有武林秘籍者相比...

     

    -----------附------------------2018.8.12-------------------------------------------------------

    该文是我几年前进行编辑的一篇文章,其中不乏出现一些不规整的错误,比如命名规范,代码冗余等,可能对于一些小伙伴们来说造成了一些困扰,不过相对来说,本文在一定程度上对javaweb的入门还是具有一定程度上的帮助。但是作为一名严谨的Java开发工程师(码猿)为了大家不再入门时就走弯路,顾我决定重新讲解javaweb方面的知识与内容,并以企业开发规范为标准来实现一个基于javaweb的小系统给大家进行参考。

    点击链接访问:基于MVC模式的Javaweb党员管理系统的设计与开发   

    https://blog.csdn.net/qq_23994787/article/details/81603737

    展开全文
  • JavaWeb——Servlet         Tomcat工作机制动画演示... Servlet(Server Applet),全称Java Servlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web...

                                 JavaWeb——Servlet

     

     

     

     

    Tomcat工作机制动画演示(点击动图可全屏观看)


     

    什么是Servlet


        

        Servlet(Server Applet),全称Java Servlet,未有中文译文。是用Java编写的服务器程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的,一般情况下,人们将Servlet理解为后者。

        Servlet运行于支持Java的应用服务器中。从实现上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议Web服务器

     

     

    Servlet的工作模式


        

    • 客户端发送请求至服务器
    • 服务器启动并调用Servlet,Servlet根据客户端请求生成响应内容并将其传给服务器
    • 服务器将响应返回客户端

     

    Servlet API 概览


        Servlet API 包含以下4个Java包:

    1.javax.servlet   其中包含定义servlet和servlet容器之间契约的类和接口。

    2.javax.servlet.http   其中包含定义HTTP Servlet 和Servlet容器之间的关系。

    3.javax.servlet.annotation   其中包含标注servlet,Filter,Listener的标注。它还为被标注元件定义元数据。

    4.javax.servlet.descriptor,其中包含提供程序化登录Web应用程序的配置信息的类型。

     

     

    Servlet 的主要类型


     

     

     

     

     

    Servlet 的使用方法


        

    Servlet技术的核心是Servlet,它是所有Servlet类必须直接或者间接实现的一个接口。在编写实现Servlet的Servlet类时,直接实现它。在扩展实现这个这个接口的类时,间接实现它。

     

    Servlet 的工作原理


     

        Servlet接口定义了Servletservlet容器之间的契约。这个契约是:Servlet容器将Servlet类载入内存,并产生Servlet实例和调用它具体的方法。但是要注意的是,在一个应用程序中,每种Servlet类型只能有一个实例

     

        用户请求致使Servlet容器调用Servlet的Service()方法,并传入一个ServletRequest对象和一个ServletResponse对象。ServletRequest对象和ServletResponse对象都是由Servlet容器(例如TomCat)封装好的,并不需要程序员去实现,程序员可以直接使用这两个对象。

        ServletRequest中封装了当前的Http请求,因此,开发人员不必解析和操作原始的Http数据。ServletResponse表示当前用户的Http响应,程序员只需直接操作ServletResponse对象就能把响应轻松的发回给用户。

        对于每一个应用程序,Servlet容器还会创建一个ServletContext对象。这个对象中封装了上下文(应用程序)的环境详情。每个应用程序只有一个ServletContext。每个Servlet对象也都有一个封装Servlet配置的ServletConfig对象。

     

     

     

    Servlet 接口中定义的方法


        让我们首先来看一看Servlet接口中定义了哪些方法吧。

     

    public interface Servlet {
        void init(ServletConfig var1) throws ServletException;
    
        ServletConfig getServletConfig();
    
        void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
    
        String getServletInfo();
    
        void destroy();
    }
    

        

    Servlet 的生命周期


    其中,init( ),service( ),destroy( )是Servlet生命周期的方法。代表了Servlet从“出生”到“工作”再到“死亡 ”的过程。Servlet容器(例如TomCat)会根据下面的规则来调用这三个方法:

    1.init( ),当Servlet第一次被请求时,Servlet容器就会开始调用这个方法来初始化一个Servlet对象出来,但是这个方法在后续请求中不会在被Servlet容器调用,就像人只能“出生”一次一样。我们可以利用init( )方法来执行相应的初始化工作。调用这个方法时,Servlet容器会传入一个ServletConfig对象进来从而对Servlet对象进行初始化

    2.service( )方法,每当请求Servlet时,Servlet容器就会调用这个方法。就像人一样,需要不停的接受老板的指令并且“工作”。第一次请求时,Servlet容器会先调用init( )方法初始化一个Servlet对象出来,然后会调用它的service( )方法进行工作,但在后续的请求中,Servlet容器只会调用service方法了。

    3.destory,当要销毁Servlet时,Servlet容器就会调用这个方法,就如人一样,到时期了就得死亡。在卸载应用程序或者关闭Servlet容器时,就会发生这种情况,一般在这个方法中会写一些清除代码。

        首先,我们来编写一个简单的Servlet来验证一下它的生命周期:

     

    public class MyFirstServlrt implements Servlet {
    
        @Override
        public void init(ServletConfig servletConfig) throws ServletException {
            System.out.println("Servlet正在初始化");
        }
    
        @Override
        public ServletConfig getServletConfig() {
            return null;
        }
    
        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
            //专门向客服端提供响应的方法
            System.out.println("Servlet正在提供服务");
    
        }
    
        @Override
        public String getServletInfo() {
            return null;
        }
    
        @Override
        public void destroy() {
            System.out.println("Servlet正在销毁");
        }
    }      

    然后在xml中配置正确的映射关系,在浏览器中访问Servlet,第一次访问时,控制台输出了如下信息:

    然后,我们在浏览器中刷新3遍

    控制台输出的信息变成了下面这样:

    接下来,我们关闭Servlet容器

    控制台输出了Servlet的销毁信息,这就是一个Servlet的完整生命周期。

     

    Servlet 的其它两个方法


        getServletInfo( ),这个方法会返回Servlet的一段描述,可以返回一段字符串。

        getServletConfig( ),这个方法会返回由Servlet容器传给init( )方法的ServletConfig对象。

     

     

    ServletRequset接口


        Servlet容器对于接受到的每一个Http请求,都会创建一个ServletRequest对象,并把这个对象传递给Servlet的Sevice( )方法。其中,ServletRequest对象内封装了关于这个请求的许多详细信息。

    让我们来看一看ServletRequest接口的部分内容:

     

    public interface ServletRequest {
      
    
        int getContentLength();//返回请求主体的字节数
    
        String getContentType();//返回主体的MIME类型
    
        String getParameter(String var1);//返回请求参数的值
    
    }

    其中,getParameter是在ServletRequest中最常用的方法,可用于获取查询字符串的值

     

     

    ServletResponse接口


        javax.servlet.ServletResponse接口表示一个Servlet响应,在调用Servlet的Service( )方法前,Servlet容器会先创建一个ServletResponse对象,并把它作为第二个参数传给Service( )方法。ServletResponse隐藏了向浏览器发送响应的复杂过程。

        让我们也来看看ServletResponse内部定义了哪些方法:

     

    public interface ServletResponse {
        String getCharacterEncoding();
    
        String getContentType();
    
        ServletOutputStream getOutputStream() throws IOException;
    
        PrintWriter getWriter() throws IOException;
    
        void setCharacterEncoding(String var1);
    
        void setContentLength(int var1);
    
        void setContentType(String var1);
    
        void setBufferSize(int var1);
    
        int getBufferSize();
    
        void flushBuffer() throws IOException;
    
        void resetBuffer();
    
        boolean isCommitted();
    
        void reset();
    
        void setLocale(Locale var1);
    
        Locale getLocale();
    }

     

       其中的getWriter方法,它返回了一个可以向客户端发送文本的的Java.io.PrintWriter对象。默认情况下,PrintWriter对象使用ISO-8859-1编码(该编码在输入中文时会发生乱码)。

     

        在向客户端发送响应时,大多数都是使用该对象向客户端发送HTML。

    还有一个方法也可以用来向浏览器发送数据,它就是getOutputStream,从名字就可以看出这是一个二进制流对象,因此这个方法是用来发送二进制数据的。

    在发送任何HTML之前,应该先调用setContentType()方法,设置响应的内容类型,并将“text/html”作为一个参数传入,这是在告诉浏览器响应的内容类型为HTML,需要以HTML的方法解释响应内容而不是普通的文本,或者也可以加上“charset=UTF-8”改变响应的编码方式以防止发生中文乱码现象。

     

     

    ServletConfig接口


        当Servlet容器初始化Servlet时,Servlet容器会给Servlet的init( )方式传入一个ServletConfig对象。

    其中几个方法如下:

     

     

    ServletContext对象


        ServletContext对象表示Servlet应用程序。每个Web应用程序都只有一个ServletContext对象。在将一个应用程序同时部署到多个容器的分布式环境中,每台Java虚拟机上的Web应用都会有一个ServletContext对象。

    通过在ServletConfig中调用getServletContext方法,也可以获得ServletContext对象。

    那么为什么要存在一个ServletContext对象呢?存在肯定是有它的道理,因为有了ServletContext对象,就可以共享从应用程序中的所有资料处访问到的信息,并且可以动态注册Web对象。前者将对象保存在ServletContext中的一个内部Map中。保存在ServletContext中的对象被称作属性。

    ServletContext中的下列方法负责处理属性:

     

    Object getAttribute(String var1);
    
    Enumeration<String> getAttributeNames();
    
    void setAttribute(String var1, Object var2);
    
    void removeAttribute(String var1);

     

     

     

     

     

    GenericServlet抽象类 


        前面我们编写Servlet一直是通过实现Servlet接口来编写的,但是,使用这种方法,则必须要实现Servlet接口中定义的所有的方法,即使有一些方法中没有任何东西也要去实现,并且还需要自己手动的维护ServletConfig这个对象的引用。因此,这样去实现Servlet是比较麻烦的。

    void init(ServletConfig var1) throws ServletException;

        幸好,GenericServlet抽象类的出现很好的解决了这个问题。本着尽可能使代码简洁的原则,GenericServlet实现了Servlet和ServletConfig接口,下面是GenericServlet抽象类的具体代码:

     

    public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
        private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
        private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.LocalStrings");
        private transient ServletConfig config;
    
        public GenericServlet() {
        }
    
        public void destroy() {
        }
    
        public String getInitParameter(String name) {
            ServletConfig sc = this.getServletConfig();
            if (sc == null) {
                throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
            } else {
                return sc.getInitParameter(name);
            }
        }
    
        public Enumeration<String> getInitParameterNames() {
            ServletConfig sc = this.getServletConfig();
            if (sc == null) {
                throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
            } else {
                return sc.getInitParameterNames();
            }
        }
    
        public ServletConfig getServletConfig() {
            return this.config;
        }
    
        public ServletContext getServletContext() {
            ServletConfig sc = this.getServletConfig();
            if (sc == null) {
                throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
            } else {
                return sc.getServletContext();
            }
        }
    
        public String getServletInfo() {
            return "";
        }
    
        public void init(ServletConfig config) throws ServletException {
            this.config = config;
            this.init();
        }
    
        public void init() throws ServletException {
        }
    
        public void log(String msg) {
            this.getServletContext().log(this.getServletName() + ": " + msg);
        }
    
        public void log(String message, Throwable t) {
            this.getServletContext().log(this.getServletName() + ": " + message, t);
        }
    
        public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
    
        public String getServletName() {
            ServletConfig sc = this.getServletConfig();
            if (sc == null) {
                throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
            } else {
                return sc.getServletName();
            }
        }
    }
    
        其中,GenericServlet抽象类相比于直接实现Servlet接口,有以下几个好处:
    

     

    1.为Servlet接口中的所有方法提供了默认的实现,则程序员需要什么就直接改什么,不再需要把所有的方法都自己实现了。

    2.提供方法,包围ServletConfig对象中的方法。

     

    3.将init( )方法中的ServletConfig参数赋给了一个内部的ServletConfig引用从而来保存ServletConfig对象,不需要程序员自己去维护ServletConfig了。

    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }

    但是,我们发现在GenericServlet抽象类中还存在着另一个没有任何参数的Init()方法:

     

    public void init() throws ServletException {
    }

    设计者的初衷到底是为了什么呢?在第一个带参数的init()方法中就已经把ServletConfig对象传入并且通过引用保存好了,完成了Servlet的初始化过程,那么为什么后面还要加上一个不带任何参数的init()方法呢?这不是多此一举吗?

        当然不是多此一举了,存在必然有存在它的道理。我们知道,抽象类是无法直接产生实例的,需要另一个类去继承这个抽象类,那么就会发生方法覆盖的问题,如果在类中覆盖了GenericServlet抽象类的init()方法,那么程序员就必须手动的去维护ServletConfig对象了,还得调用super.init(servletConfig)方法去调用父类GenericServlet的初始化方法来保存ServletConfig对象,这样会给程序员带来很大的麻烦。GenericServlet提供的第二个不带参数的init( )方法,就是为了解决上述问题的。

        这个不带参数的init()方法,是在ServletConfig对象被赋给ServletConfig引用后,由第一个带参数的init(ServletConfig servletconfig)方法调用的,那么这意味着,当程序员如果需要覆盖这个GenericServlet的初始化方法,则只需要覆盖那个不带参数的init( )方法就好了,此时,servletConfig对象仍然有GenericServlet保存着。

        说了这么多,通过扩展GenericServlet抽象类,就不需要覆盖没有计划改变的方法。因此,代码将会变得更加的简洁,程序员的工作也会减少很多。

        然而,虽然GenricServlet是对Servlet一个很好的加强,但是也不经常用,因为他不像HttpServlet那么高级。HttpServlet才是主角,在现实的应用程序中被广泛使用。那么我们接下来就看看传说中的HttpServlet到底厉害在哪里吧。

     

     

    javax.servlet.http包内容


        之所以所HttpServlet要比GenericServlet强大,其实也是有道理的。HttpServlet是由GenericServlet抽象类扩展而来的,HttpServlet抽象类的声明如下所示:

     

    public abstract class HttpServlet extends GenericServlet implements Serializable 

    HttpServlet之所以运用广泛的另一个原因是现在大部分的应用程序都要与HTTP结合起来使用。这意味着我们可以利用HTTP的特性完成更多更强大的任务。Javax。servlet.http包是Servlet API中的第二个包,其中包含了用于编写Servlet应用程序的类和接口。Javax.servlet.http中的许多类型都覆盖了Javax.servlet中的类型。

     

     

    HttpServlet抽象类


        HttpServlet抽象类是继承于GenericServlet抽象类而来的。使用HttpServlet抽象类时,还需要借助分别代表Servlet请求和Servlet响应的HttpServletRequest和HttpServletResponse对象。

    HttpServletRequest接口扩展于javax.servlet.ServletRequest接口,HttpServletResponse接口扩展于javax.servlet.servletResponse接口。

     

    public interface HttpServletRequest extends ServletRequest
    public interface HttpServletResponse extends ServletResponse

    HttpServlet抽象类覆盖了GenericServlet抽象类中的Service( )方法,并且添加了一个自己独有的Service(HttpServletRequest request,HttpServletResponse方法。

    让我们来具体的看一看HttpServlet抽象类是如何实现自己的service方法吧:

        首先来看GenericServlet抽象类中是如何定义service方法的:

     

    public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    我们看到是一个抽象方法,也就是HttpServlet要自己去实现这个service方法,我们在看看HttpServlet是怎么覆盖这个service方法的:

     

    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        HttpServletRequest request;
        HttpServletResponse response;
        try {
            request = (HttpServletRequest)req;
            response = (HttpServletResponse)res;
        } catch (ClassCastException var6) {
            throw new ServletException("non-HTTP request or response");
        }
    
        this.service(request, response);
    }

        我们发现,HttpServlet中的service方法把接收到的ServletRequsest类型的对象转换成了HttpServletRequest类型的对象,把ServletResponse类型的对象转换成了HttpServletResponse类型的对象。之所以能够这样强制的转换,是因为在调用Servlet的Service方法时,Servlet容器总会传入一个HttpServletRequest对象和HttpServletResponse对象,预备使用HTTP。因此,转换类型当然不会出错了。

        转换之后,service方法把两个转换后的对象传入了另一个service方法,那么我们再来看看这个方法是如何实现的:

     

    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        long lastModified;
        if (method.equals("GET")) {
            lastModified = this.getLastModified(req);
            if (lastModified == -1L) {
                this.doGet(req, resp);
            } else {
                long ifModifiedSince = req.getDateHeader("If-Modified-Since");
                if (ifModifiedSince < lastModified) {
                    this.maybeSetLastModified(resp, lastModified);
                    this.doGet(req, resp);
                } else {
                    resp.setStatus(304);
                }
            }
        } else if (method.equals("HEAD")) {
            lastModified = this.getLastModified(req);
            this.maybeSetLastModified(resp, lastModified);
            this.doHead(req, resp);
        } else if (method.equals("POST")) {
            this.doPost(req, resp);
        } else if (method.equals("PUT")) {
            this.doPut(req, resp);
        } else if (method.equals("DELETE")) {
            this.doDelete(req, resp);
        } else if (method.equals("OPTIONS")) {
            this.doOptions(req, resp);
        } else if (method.equals("TRACE")) {
            this.doTrace(req, resp);
        } else {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[]{method};
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(501, errMsg);
        }
    
    }

     

        我们发现,这个service方法的参数是HttpServletRequest对象和HttpServletResponse对象,刚好接收了上一个service方法传过来的两个对象。

     

        接下来我们再看看service方法是如何工作的,我们会发现在service方法中还是没有任何的服务逻辑,但是却在解析HttpServletRequest中的方法参数,并调用以下方法之一:doGet,doPost,doHead,doPut,doTrace,doOptions和doDelete。这7种方法中,每一种方法都表示一个Http方法。doGet和doPost是最常用的。所以,如果我们需要实现具体的服务逻辑,不再需要覆盖service方法了,只需要覆盖doGet或者doPost就好了。

        总之,HttpServlet有两个特性是GenericServlet所不具备的:

        1.不用覆盖service方法,而是覆盖doGet或者doPost方法。在少数情况,还会覆盖其他的5个方法。

        2.使用的是HttpServletRequest和HttpServletResponse对象。

     

     

    HttpServletRequest接口


        

        HttpServletRequest表示Http环境中的Servlet请求。它扩展于javax.servlet.ServletRequest接口,并添加了几个方法。

     

     

    String getContextPath();//返回请求上下文的请求URI部分
    Cookie[] getCookies();//返回一个cookie对象数组
    String getHeader(String var1);//返回指定HTTP标题的值
    String getMethod();//返回生成这个请求HTTP的方法名称
    String getQueryString();//返回请求URL中的查询字符串
    HttpSession getSession();//返回与这个请求相关的会话对象

    HttpServletRequest内封装的请求


        因为Request代表请求,所以我们可以通过该对象分别获得HTTP请求的请求行,请求头和请求体。

        关于HTTP具体的详细解释,可以参考我的另一篇博文:JavaWeb——HTTP。

     

    通过request获得请求行


     

    假设查询字符串为:username=zhangsan&password=123

    获得客户端的请求方式:String getMethod()

    获得请求的资源:

    String getRequestURI()

    StringBuffer getRequestURL()

    String getContextPath() ---web应用的名称

    String getQueryString() ---- get提交url地址后的参数字符串

     

    通过request获得请求头


    long getDateHeader(String name)

    String getHeader(String name)

    Enumeration getHeaderNames()

    Enumeration getHeaders(String name)

    int getIntHeader(String name)

    referer头的作用:执行该此访问的的来源,做防盗链

     

    通过request获得请求体


    请求体中的内容是通过post提交的请求参数,格式是:

    username=zhangsan&password=123&hobby=football&hobby=basketball

    key ---------------------- value

    username                               [zhangsan]

    password                               [123]

    hobby                                          [football,basketball]                                       

    以上面参数为例,通过一下方法获得请求参数:

    String getParameter(String name)

    String[] getParameterValues(String name)

    Enumeration getParameterNames()

    Map<String,String[]> getParameterMap()

          注意:get请求方式的请求参数 上述的方法一样可以获得。

     

     

    Request乱码问题的解决方法


        在前面我们讲过,在service中使用的编码解码方式默认为:ISO-8859-1编码,但此编码并不支持中文,因此会出现乱码问题,所以我们需要手动修改编码方式为UTF-8编码,才能解决中文乱码问题,下面是发生乱码的具体细节:

     

     

     

    解决post提交方式的乱码:request.setCharacterEncoding("UTF-8");

     解决get提交的方式的乱码:

    parameter = newString(parameter.getbytes("iso8859-1"),"utf-8");

     

    HttpServletResponse接口


     

        在Service API中,定义了一个HttpServletResponse接口,它继承自ServletResponse接口,专门用来封装HTTP响应消息。    由于HTTP请求消息分为状态行,响应消息头,响应消息体三部分,因此,在HttpServletResponse接口中定义了向客户端发送响应状态码,响应消息头,响应消息体的方法。

     

     

    HttpServletResponse内封装的响应


     

     

     

    通过Response设置响应


     

     

     

    void addCookie(Cookie var1);//给这个响应添加一个cookie
    void addHeader(String var1, String var2);//给这个请求添加一个响应头
    void sendRedirect(String var1) throws IOException;//发送一条响应码,讲浏览器跳转到指定的位置
    void setStatus(int var1);//设置响应行的状态码

    addHeader(String name, String value)

    addIntHeader(String name, int value)

    addDateHeader(String name, long date)

    setHeader(String name, String value)

    setDateHeader(String name, long date)

    setIntHeader(String name, int value)

    其中,add表示添加,而set表示设置

     

    PrintWriter getWriter()

    获得字符流,通过字符流的write(String s)方法可以将字符串设置到response   缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端。

    ServletOutputStream getOutputStream()

    获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字节,再由Tomcat服务器将字节内容组成Http响应返回给浏览器。

     

     注意:虽然response对象的getOutSream()和getWriter()方法都可以发送响应消息体,但是他们之间相互排斥,不可以同时使用,否则会发生异常。

     

    Response的乱码问题


     

    原因:response缓冲区的默认编码是iso8859-1,此码表中没有中文。所以需要更改response的编码方式:

     

        通过更改response的编码方式为UTF-8,任然无法解决乱码问题,因为发送端服务端虽然改变了编码方式为UTF-8,但是接收端浏览器端仍然使用GB2312编码方式解码,还是无法还原正常的中文,因此还需要告知浏览器端使用UTF-8编码去解码

        上面通过调用两个方式分别改变服务端对于Response的编码方式以及浏览器的解码方式为同样的UTF-8编码来解决编码方式不一样发生乱码的问题。

    response.setContentType("text/html;charset=UTF-8")这个方法包含了上面的两个方法的调用,因此在实际的开发中,只需要调用一个response.setContentType("text/html;charset=UTF-8")方法即可。

     

    Response的工作流程


     

     

    Servlet的工作流程


     

     

    编写第一个Servlet


        首先,我们来写一个简单的用户名,密码的登录界面的html文件:

    <form action="/form" method="get">

    该html文件在最后点击提交按钮时,把表单所有数据通过Get方式发送到/form虚拟路径下:

     

     

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form action="/form" method="get">
        <span>用户名</span><input type="text" name="username"><br>
        <span>密码</span><input type="password" name="password"><br>
        <input type="submit" name="submit">
    </form>
    
    </body>
    </html>

    访问一下我们刚才写的这个简单的登录界面:

        接下来,我们就开始写一个Servlet用来接收处理表单发送过来的请求,这个Servlet的名称就叫做FormServlet:

     

    public class FormServlet extends HttpServlet {
        private static final long serialVersionUID = -4186928407001085733L;
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        }
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
             //设置响应的编码格式为UTF-8编码,否则发生中文乱码现象
            response.setContentType("text/html;charset=UTF-8");
            //1.获得请求方式
            String method = request.getMethod();
            //2.获得请求的资源相关的内容
            String requestURI = request.getRequestURI();//获得请求URI
            StringBuffer requestURL = request.getRequestURL();
            String webName = request.getContextPath();//获得应用路径(应用名称)
            String querryString = request.getQueryString();//获得查询字符串
    
            response.getWriter().write("<h1>下面是获得的字符串</h1>");
            response.getWriter().write("<h1>method(HTTP方法):<h1>");
            response.getWriter().write("<h1>"+method+"</h1><br>");
            response.getWriter().write("<h1>requestURi(请求URI):</h1>");
            response.getWriter().write("<h1>" + requestURI + "</h1><br>");
            response.getWriter().write("<h1>webname(应用名称):</h1>");
            response.getWriter().write("<h1>" + webName + "</h1><br>");
            response.getWriter().write("<h1>querrystring(查询字符串):</h1>");
            response.getWriter().write("<h1>" + querryString + "</h1>");
    
    
        }
    }

        该Servlet的作用是,接收form登录表单发送过来的HTTP请求,并解析出请求中封装的一些参数,然后在回写到response响应当中去,最后在浏览器端显示。

        最后一步,我们在XML中配置好这个Servlet的映射关系:

     

    </servlet-mapping>
        <servlet>
            <servlet-name>FormServlet</servlet-name>
            <servlet-class>com.javaee.util.FormServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>FormServlet</servlet-name>
            <url-pattern>/form</url-pattern>
        </servlet-mapping>

        接下来,启动tomcat,在浏览器中输入登录表单的地址:

    填入用户名为:root,密码为:123,最后点击提交:

    提交之后,表单数据将会发送到相应的Servlet进行处理,此时,浏览器的地址变成如下所示:

        我们会发现,在地址栏中,多了后面的“?username=root&password=123&提交=提交”字符串,这其实就是我们开始填写的参数,以Get的方法发送过去,所以查询字符串会直接加在链接后面,如果采用的是Post方式则不会出现在链接中,因此,登录表单为了安全性大多采用Post方式提交。

        我们来看看Servlet给我们返回了什么东西:

        正如我们在Servlet中写的那样,Servlet把HTTP请求中的部分参数给解析出来了。

    因此,可以再翻到上面的Servlet重新去理解一遍Servlet的工作原理,可能会有更清晰的认识。

     

     

    Servlet的局限性


     

        我们已经看到,Servlet如果需要给客户端返回数据,比如像下面这样的一个HTML文件:

     

    Servlet内部需要这样写输出语句:

     

    PrintWriter writer = response.getWriter();
    writer.write("<!DOCTYPE html>\n" +
            "<html>\n" +
            "\t<head>\n" +
            "\t\t<meta charset=\"UTF-8\">\n" +
            "\t\t<title>标题标签</title>\n" +
            "\t</head>\n" +
            "\t<body>\n" +
            "\t\t<!--标题标签-->\n" +
            "\t\t<h1>公司简介</h1><br />\n" +
            "\t\t<h2>公司简介</h2><br />\n" +
            "\t\t<h3>公司简介</h3><br />\n" +
            "\t\t<h4>公司简介</h4><br />\n" +
            "\t\t\n" +
            "\t\t<!--加入一条水平线-->\n" +
            "\t\t<hr />\n" +
            "\t\t\n" +
            "\t\t<h5>公司简介</h5><br />\n" +
            "\t\t<h6>公司简介</h7><br />\n" +
            "\t\t<h100>公司简介</h100>\n" +
            "\t</body>\n" +
            "</html>\n");

        即一行一行的把HTML语句给用Writer输出,早期简单的网页还能应付得住,但是随着互联网的不断发展,网站的内容和功能越来越强大,一个普通的HTML文件可能就达到好几百行,如果在采用使用Servlet去一行一行的输出HTML代码的话,将会非常的繁琐并且浪费大量的时间,且在当时,出现了PHP这种可以内嵌到HTML文件的动态语言,使得制作动态网页变得异常的简单和轻松,因此大量的程序员转上了PHP语言的道路,JAVA的份额急剧减小,当时JAVA的开发者Sun公司为了解决这个问题,也开发出了自己的动态网页生成技术,使得同样可以在HTML文件里内嵌JAVA代码,这就是现在的JSP技术,关于JSP技术的具体内容,我们将留到下一节进行讲解。

     

    ServletContextListener(Servlet全局监听器)


    首先要说明的是,ServletContextListener是一个接口,我们随便写一个类,只要这个类实现了ServletContextListener接口,那么这个类就实现了【监听ServletContext】的功能。那么,这个神奇的接口是如何定义的呢?我们来看一下这个接口的内部情况:

    package javax.servlet;

    import java.util.EventListener;

    public interface ServletContextListener extends EventListener {
       
    void contextInitialized(ServletContextEvent var1);


        void contextDestroyed(ServletContextEvent var1);
    }

    我们发现,在这个接口中只声明了两个方法,分别是void contextInitialized(ServletContextEvent var1)和void contextDestroyed(ServletContextEvent var1)方法,所以,我们很容易的就能猜测到,ServletContext的生命只有两种,分别是:

    1.ServletContext初始化。(应用start时)---------->Servlet容器调用void contextInitialized(ServletContextEvent var1)

    2.ServletContext销毁。(应用stop时)---------->Servlet容器调用 void contextDestroyed(ServletContextEvent var1)

    因此,我们大概能够猜到ServletContextListener的工作机制了,当应用启动时,ServletContext进行初始化,然后Servlet容器会自动调用正在监听ServletContext的ServletContextListener的void contextInitialized(ServletContextEvent var1)方法,并向其传入一个ServletContextEvent对象。当应用停止时,ServletContext被销毁,此时Servlet容器也会自动地调用正在监听ServletContext的ServletContextListener的void contextDestroyed(ServletContextEvent var1)方法。

    为了验证我们的猜测,我们来随便写一个类,并且实现ServletContextListener接口,即实现监听ServletContext的功能:

    import javax.servlet.ServletContextEvent;

    import javax.servlet.ServletContextListener;

    public class MyListener implements ServletContextListener {

        @Override

        public void contextInitialized(ServletContextEvent servletContextEvent) {

            System.out.println("ServletContextListener.contextInitialized方法被调用");

        }

        @Override

        public void contextDestroyed(ServletContextEvent servletContextEvent) {

            System.out.println("ServletContextListener.contextDestroyed方法被调用");

        }

    }

    然后,在web.xml中注册我们自己写的这个MyListener:

    <?xml version="1.0" encoding="UTF-8"?>

    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"

             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"

             version="4.0">

        <listener>

            <listener-class>MyListener</listener-class>

        </listener>

    </web-app>

    接下来,让我们启动一下Tomcat,看一看会发生什么吧!控制台打印信息如下:

     

    我们发现,当应用启动时,ServletContextListener.contextInitialized()方法被调用了。这其实是Servlet容器偷偷干的事情。那么,当我们停止Tomcat时,按照猜想,Servlet容器应该也会偷偷调用void contextDestroyed(ServletContextEvent var1)方法,来通知ServletContextListener监听器:ServletContext已经被销毁了。那么,事实是不是和我们猜想的一模一样呢?让我们来停止Tomcat的运行,看一看控制台的情况吧:

     

    我们发现,void contextDestroyed(ServletContextEvent var1)方法确实被Servlet容器调用了。因此,我们的猜想得到了证实。

    【进阶】ServletContextListener在Spring中的应用


    如果基础好一点的童鞋,或者已经学过Spring框架的同学,建议阅读下面的内容,没有学过Spring也没有关系,可以先学或者学完之后再回头来看一看,Spring容器是如何借用ServletContextListener这个接口来实例化的。

    首先让我们再来回顾一下ServletContext的概念,ServletContext翻译成中文叫做“Servlet上下文”或者“Servlet全局”,但是这个翻译我认为翻译的实在是有点牵强,也导致了许多的开发者不明白这个变量到底具体代表了什么。其实ServletContext就是一个“域对象”,它存在于整个应用中,并在在整个应用中有且仅有1份,它表示了当前整个应用的“状态”,你也可以理解为某个时刻的ServletContext代表了这个应用在某个时刻的“一张快照”,这张“快照”里面包含了有关应用的许多信息,应用的所有组件都可以从ServletContext获取当前应用的状态信息。ServletContext随着程序的启动而创建,随着程序的停止而销毁。通俗点说,我们可以往这个ServletContext域对象中“存东西”,然后也可以在别的地方中“取出来”。

    我们知道,Spring容器可以通过:

    ApplicationContext ctx=new ClassPathXmlApplicationContext("配置文件的路径");

    显示地实例化一个Spring IOC容器。也可以像下面一样,在web.xml中注册Spring IOC容器:

    <listener>

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

    </listener>

    <context-param>

        <param-name>contextConfigLocation</param-name>

        <param-value>

            classpath:applicationContext.xml

        </param-value>

    </context-param>

    其中的监听器类【org.springframework.web.context.ContextLoaderListener】实现了ServletContextListener接口,能够监听ServletContext的生命周期中的“初始化”和“销毁”。注意,这个【org.springframework.web.context.ContextLoaderListener】监听器类当然不是我们自己写的哦,是人家Spring团队写的,我们只要拿来用就行了。当然,别忘记导入相关的Jar包。(spring-web-4.2.4.RELEASE.jar

    那么,Spring团队给我们提供的这个监听器类是如何实现:当ServletContext初始化后,Spring IOC容器也能跟着初始化的呢?怀着好奇心,让我们再来看一看【org.springframework.web.context.ContextLoaderListener】的内部实现情况吧。

     

     

    package org.springframework.web.context;

    import javax.servlet.ServletContextEvent;

    import javax.servlet.ServletContextListener;

    public class ContextLoaderListener extends ContextLoader implements ServletContextListener {

        public ContextLoaderListener() {

        }

        public ContextLoaderListener(WebApplicationContext context) {

            super(context);

        }

    --------------------------------------------------------重点关注下面这里哦!-----------------------------------------------------------------------

        public void contextInitialized(ServletContextEvent event) {

            this.initWebApplicationContext(event.getServletContext());

        }

    --------------------------------------------------------重点关注上面这里哦!-----------------------------------------------------------------------

        public void contextDestroyed(ServletContextEvent event) {

            this.closeWebApplicationContext(event.getServletContext());

            ContextCleanupListener.cleanupAttributes(event.getServletContext());

        }

    }

    我们发现,【org.springframework.web.context.ContextLoaderListener】这个类实现了ServletContextListener接口中的两个方法,其中,当ServletContext初始化后, public void contextInitialized(ServletContextEvent event)方法被调用,接下来执行initWebApplicationContext(event.getServletContext())方法,但是我们发现这个方法并没有在这个类中声明,因此,我们再看一下其父类中是如何声明的:

     

    public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
    
        if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
    
            throw new IllegalStateException("Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!");
    
        } else {
    
            Log logger = LogFactory.getLog(ContextLoader.class);
    
            servletContext.log("Initializing Spring root WebApplicationContext");
    
            if (logger.isInfoEnabled()) {
    
                logger.info("Root WebApplicationContext: initialization started");
    
            }
    
    
    
            long startTime = System.currentTimeMillis();
    
    
    
            try {
    
                if (this.context == null) {
    
                    this.context = this.createWebApplicationContext(servletContext);
    
                }
    
    
    
                if (this.context instanceof ConfigurableWebApplicationContext) {
    
                    ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)this.context;
    
                    if (!cwac.isActive()) {
    
                        if (cwac.getParent() == null) {
    
                            ApplicationContext parent = this.loadParentContext(servletContext);
    
                            cwac.setParent(parent);
    
                        }
    
    
    
                        this.configureAndRefreshWebApplicationContext(cwac, servletContext);
    
                    }
    
                }
    
    
    
                servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
    
                ClassLoader ccl = Thread.currentThread().getContextClassLoader();
    
                if (ccl == ContextLoader.class.getClassLoader()) {
    
                    currentContext = this.context;
    
                } else if (ccl != null) {
    
                    currentContextPerThread.put(ccl, this.context);
    
                }
    
    
    
                if (logger.isDebugEnabled()) {
    
                    logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
    
                }
    
    
    
                if (logger.isInfoEnabled()) {
    
                    long elapsedTime = System.currentTimeMillis() - startTime;
    
                    logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
    
                }
    
    
    
                return this.context;
    
            } catch (RuntimeException var8) {
    
                logger.error("Context initialization failed", var8);
    
                servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, var8);
    
                throw var8;
    
            } catch (Error var9) {
    
                logger.error("Context initialization failed", var9);
    
                servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, var9);
    
                throw var9;
    
            }
    
        }
    
    }

     

     

     

     

    分析到这一步,我们发现Spring容器在这个方法中被实例化了。接下来,就让我们整理一下整体的思路:

    当Servlet容器启动时,ServletContext对象被初始化,然后Servlet容器调用web.xml中注册的监听器的

    public void contextInitialized(ServletContextEvent event)

    方法,而在监听器中,调用了this.initWebApplicationContext(event.getServletContext())方法,在这个方法中实例化了Spring IOC容器。即ApplicationContext对象。

    因此,当ServletContext创建时我们可以创建applicationContext对象,当ServletContext销毁时,我们可以销毁applicationContext对象。这样applicationContext就和ServletContext“共生死了”。

     

    参考资料


     

    【1】 维基百科-Servlet

    【2】Servlet、JSP和Spring MVC初学指南 【加】Buid Kurniawan 【美】Paul Deck 著 林仪明 俞黎敏 译 中国工信出版社 

     

    博客文章版权说明


     

     

     

    第一条 本博客文章仅代表作者本人的观点,不保证文章等内容的有效性。

    第二条 本博客部分内容转载于合作站点或摘录于部分书籍,但都会注明作/译者和原出处。如有不妥之处,敬请指出。

    第三条 征得本博客作者同意的情况下,本博客的作品允许非盈利性引用,并请注明出处:“作者:____转载自____”字样,以尊重作者的劳动成果。版权归原作/译者所有。未经允许,严禁转载

    第四条 对非法转载者,“扬俊的小屋”和作/译者保留采用法律手段追究的权利

    第五条 本博客之声明以及其修改权、更新权及最终解释权均属“扬俊的小屋”。

    第六条 以上声明的解释权归扬俊的小屋所有。

     

     

     

     

     

    展开全文
  • 手把手搭建一个完整的javaweb项目(适合新手)

    万次阅读 多人点赞 2019-03-17 15:51:39
    致谢:在此感谢落尘曦的参考博文,附上原文地址 说明:只是实现了简单的操作,但是逻辑并不严谨,仅适合新手,望注意。 开发环境与工具 IntelliJ IDEA 2018.3.3(Ultimate Edition) Mysql Workbench8.0 ...

    本篇文章仅供参考。如果您遇到了问题,建议自己使用英文进行google搜索。而不是当一个不经过自己努力和思考的伸手党

    说明1:只是实现了简单的操作,但是逻辑并不严谨(比如并没有进行密码的加密,也没有进行对不规范字符串的判断),仅适合新手,望注意。
    说明2:这个项目是在我的macbookpro上运行的。windows用户的环境配置可能不一样。望注意
    前提:正确建立了一个javaweb项目(web项目建立教程

    开发环境与工具

    1. IntelliJ IDEA 2018.3.3(Ultimate Edition)(Mac版本)
    2. Mysql Workbench8.0
    3. jdk11
    4. Tomcat for mac ( 安装教程 )

    工具包
    添加下包三个jar包,放到lib文件夹中。 jar包链接
    密码:rglh
    在这里插入图片描述
    功能说明

    1. 用户登录
    2. 新用户注册
    3. 用户列表展示
    4. 用户信息删除
    5. 用户信息更新

    操作步骤

    1. 在mysql建立一个新表Student,里面有name,password,id(为了简化操作,所以只有三列并且都是String类型)
    create table if not exists Student (name varchar(10) primary key,
    password varchar(10) not  null,
    id varchar(10) not null);
    
    1. 插入数据
    insert into Student(name,password,id) values("005",123,5);
    insert into Student(name,password,id) values("004",123,4);
    insert into Student(name,password,id) values("003",123,3);
    insert into Student(name,password,id) values("002",123,2);
    insert into Student(name,password,id) values("001",123,1);
    
    1. 打开intellij新建一个javaweb项目,具体操作参考我的博客
    2. 导入连接数据库的jar包,具体操作参考我的博客 intellij导数据库jar包
    3. 建立对应的包结构
      filter //过滤器,解决中文字符集乱码
      util //数据库连接工具类
      entity //实体类
      dao //数据操作类
      servlet //servlet类
      ![在这里插入图片描述](https://img-blog.csdnimg.cn/2019031619130537.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3l1cm9uZzMzMzMz,size_16,color_FFFFFF,t_70
    4. 在filter下新建一个EncodingFilter用来解决中文字符集乱码,它需要实现Filter接口,并重写doFilter函数
    package filter;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    //在filter下新建一个EncodingFilter用来解决中文字符集乱码,它需要实现Filter接口,并重写doFilter函数
    public class EncodingFilter implements Filter {
        public EncodingFilter() {
            System.out.println("过滤器构造");
        }
        
        public void destroy() {
            System.out.println("过滤器销毁");
        }
        
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            request.setCharacterEncoding("utf-8"); //将编码改为utf-8
            response.setContentType("text/html;charset=utf-8");
            chain.doFilter(request, response);
        }
        
        public void init(FilterConfig arg0) throws ServletException {
            System.out.println("过滤器初始化");
        }
    }
    
    
    1. web.xml的全部配置信息
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
             
        <display-name></display-name>
        
        <filter><!-- 过滤器配置-->
            <filter-name>EncodingFilter</filter-name>
            <filter-class>filter.EncodingFilter</filter-class><!--全路径 从根包开始一直到类名-->
        </filter>
    
        <filter-mapping>
            <filter-name>EncodingFilter</filter-name>
            <url-pattern>/*</url-pattern> <!--*即为过滤所有-->
        </filter-mapping>
        
        <servlet><!--servlet类路径配置-->
            <servlet-name>loginServlet</servlet-name>
            <servlet-class>servlet.loginServlet</servlet-class>
        </servlet>
    
        <servlet>
            <servlet-name>registerServlet</servlet-name>
            <servlet-class>com.servlet.registerServlet</servlet-class>
        </servlet>
        
        <servlet>
            <servlet-name>showAllServlet</servlet-name>
            <servlet-class>servlet.showAllServlet</servlet-class>
        </servlet>
        
        <servlet>
            <servlet-name>deleteServlet</servlet-name>
            <servlet-class>com.servlet.deleteServlet</servlet-class>
        </servlet>
        
        <servlet>
            <servlet-name>updateServlet</servlet-name>
            <servlet-class>servlet.updateServlet</servlet-class>
        </servlet>
        
        <servlet-mapping><!--servlet类映射配置-->
            <servlet-name>loginServlet</servlet-name>
            <url-pattern>/loginServlet</url-pattern>
        </servlet-mapping>
        
        <servlet-mapping>
            <servlet-name>registerServlet</servlet-name>
            <url-pattern>/registerServlet</url-pattern>
        </servlet-mapping>
        
        <servlet-mapping>
            <servlet-name>showAllServlet</servlet-name>
            <url-pattern>/showAllServlet</url-pattern>
        </servlet-mapping>
        
        <servlet-mapping>
            <servlet-name>deleteServlet</servlet-name>
            <url-pattern>/deleteServlet</url-pattern>
        </servlet-mapping>
        
        <servlet-mapping>
            <servlet-name>updateServlet</servlet-name>
            <url-pattern>/updateServlet</url-pattern>
        </servlet-mapping>
        
        <welcome-file-list><!--默认首页地址-->
            <welcome-file>login.jsp</welcome-file>
        </welcome-file-list>
        
    </web-app>
    
    
    
    1. 在util下新建一个DBconnect类用来处理对数据库的连接操作(用户名或密码按照自己的数据库更改)
    package com.util;
    import java.sql.*;
    public class DBconnect
    {
        static String url="jdbc:mysql://localhost:3306/DataTest?useSSL=false";
        static String user="root";
        static String pw = "12345678";
        static Connection conn=null;
        static PreparedStatement ps=null;
        static ResultSet rs=null;
        static Statement st=null;
    
        public static void init() throws SQLException, ClassNotFoundException {//SQl程序初始化
            try{
                Class.forName("com.mysql.jdbc.Driver");//注册驱动
                conn= DriverManager.getConnection(url, user, pw);  //建立连接
            }catch (Exception e){
                System.out.println("SQL程序初始化失败");
                e.printStackTrace();
            }
        }
    
        public static int addUpdateDelete(String sql){
            int i=0;
            try{
                ps=conn.prepareStatement(sql);
                boolean flag= ps.execute();
                if(flag==false){//如果第一个结果是结果集对象,则返回true;如果第一个结果是更新计数或者没有结果,则返回false
                    i++;
                }
            }catch(Exception e){
                System.out.println("数据库增删改异常 ");
                e.printStackTrace();
            }
            return i;
        }
    
        public static ResultSet selectSql(String sql){
            try{
                ps=conn.prepareStatement(sql);
                rs=ps.executeQuery();
    
            }catch(Exception e){
                System.out.println("数据库查询异常");
                e.printStackTrace();
            }
            return rs;
        }
    
        public static  void closeConn(){
            try{
                conn.close();
            }catch(Exception e){
                System.out.println("数据库关闭异常");
                e.printStackTrace();
            }
        }
    }
    
    1. 在entity下新建一个MyUser实体类(实体即抽象出来的用户对象,对应数据库中的Student表,表中每个字段在实体中为一个属性,也可以理解为一个User对象对应数据库中的Student表一条记录)
    package entity;
    
    public class MyUser {
        private String name;
        private String password;
        private String id;
        
        public MyUser(){}
    
        public MyUser(String name,String password,String id){
            this.name=name;
            this.password=password;
            this.id=id;
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
        
    
        public MyUser(String name, String password) {
            this.name = name;
            this.password = password;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String username) {
            this.name = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
    
    }
    
    
    1. 在dao下新建一个UserDao接口 以及对应的方法实现类(使用接口类是为了规范开发)

    UserDao类

    package dao;
    import java.util.List;
    import entity.MyUser;
    
    public interface UserDao {
        public boolean login(String name,String password);
        public boolean register(MyUser user);
        public List<MyUser> getUserAll();//返回用户信息集合
        public boolean delete(String id);//根据id删除
        public boolean update(String name, String id);
    }
    
    

    UserDaoImplement类

    package dao;
    
    import entity.MyUser;
    import util.DBconnect;
    
    import java.lang.invoke.MutableCallSite;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;
    
    public class UserDaoImplement implements UserDao {
        public boolean login(String name, String password) {
            boolean flag = false;
            try {
                try{
                    DBconnect.init();
                }catch (Exception e){
                    e.printStackTrace();
                }
                //注意查询语句中的单引号双引号
                ResultSet rs = DBconnect.selectSql("select * from student where name='" + name + " 'and password='" + password + "';");
                while (rs.next()) {
                    if (rs.getString("name").equals(name) && rs.getString("password").equals(password)) {
                        flag = true;
                    }
                }
                DBconnect.closeConn();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return flag;
        }
    
        public boolean register(MyUser user) {
            boolean flag = false;
            try{
                DBconnect.init();
            }catch (Exception e){
                e.printStackTrace();
            }
            int i = DBconnect.addUpdateDelete("insert into student(name,password,id) " +
                    "values('" + user.getName() + "','" + user.getPassword() + "','"+user.getId()+" ' )");
            if (i > 0) {
                flag = true;
            }
            DBconnect.closeConn();
            return flag;
        }
    
        public List<MyUser> getUserAll() {//返回用户信息集合
            List<MyUser> list = new ArrayList<>();
            try {
                try{
                    DBconnect.init();
                }catch (Exception e){
                    e.printStackTrace();
                }
                ResultSet rs = DBconnect.selectSql("select * from student");
                while (rs.next()) {
                    String nameone=rs.getString("name");
                    String passwordone=rs.getString("password");
                    String idone=rs.getString("id");
                    MyUser user=new MyUser(nameone,passwordone,idone);
                    list.add(user);
                }
                DBconnect.closeConn();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return list;
        }
    
        public boolean delete(String id) {//根据id删除{
            boolean flag = false;
            try{
                DBconnect.init();
            }catch (Exception e){
                e.printStackTrace();
            }
            String sql = "delete from student where id='" + id+"'";
            int i = DBconnect.addUpdateDelete(sql);//i的意义:
            if (i > 0) {
                flag = true;
            }
            DBconnect.closeConn();
            return flag;
        }
    
        public boolean update(String name, String id) {
            boolean flag = false;
            try{
                DBconnect.init();
            }catch (Exception e){
                e.printStackTrace();
            }
            String sql = "update student set name ='" + name
    
                    +"'"+"where id = '" + id+"'";
    
            int i = DBconnect.addUpdateDelete(sql);
            System.out.println("1"+" "+i);
            if (i > 0) {
                flag = true;
            }
            DBconnect.closeConn();
            return flag;
        }
    
    }
    
    
    1. 在servlet下创建loginServlet用来实现对用户登录的操作
    package servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import dao.UserDao;
    import dao.UserDaoImplement;
    
    public class loginServlet extends HttpServlet {  //需要继承HttpServlet  并重写doGet  doPost方法
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);  //将信息使用doPost方法执行   对应jsp页面中的form表单中的method
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String name = request.getParameter("name"); //得到jsp页面传过来的参数
            String password = request.getParameter("password");
    
            UserDao ud = new UserDaoImplement();
    
            if (ud.login(name, password)) {
                //request.setAttribute("hello", "欢迎用户" + name); //向request域中放置信息
              request.getRequestDispatcher("/success.jsp").forward(request, response);//转发到成功页面
            } else {
                response.sendRedirect("login.jsp"); //重定向到首页
            }
        }
    }
    
    1. 在servlet下创建一个registerServlet用来实现用户注册的操作
    package com.servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Date;
    import java.text.*;
    
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import dao.UserDao;
    import dao.UserDaoImplement;
    import entity.MyUser;
    
    public class registerServlet extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doPost(request, response);
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            String name = request.getParameter("name"); //获取jsp页面传过来的参数
            String pwd = request.getParameter("password");
            String id = request.getParameter("id");
    
            MyUser user = new MyUser(); //实例化一个对象,组装属性
            user.setName(name);
            user.setPassword(pwd);
            user.setId(id);
    
            UserDao ud = new UserDaoImplement();
    
            if(ud.register(user)){
                request.setAttribute("name", name);  //向request域中放置参数
                request.getRequestDispatcher("/login.jsp").forward(request, response);  //转发到登录页面
            }else{
                response.sendRedirect("register.jsp");//注册失败则返回注册页面,但是缺少提示"注册失败"
            }
        }
    }
    
    1. 在servlet下创建shouAllServlet用来返回数据库中所有用户信息
    package servlet;
    import java.io.IOException;
    import java.util.List;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import dao.UserDao;
    import dao.UserDaoImplement;
    import entity.MyUser;
    
    public class showAllServlet extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doPost(request, response);
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            response.setContentType("text/html;charset=utf-8");
            UserDao ud = new UserDaoImplement();
            List<MyUser> userAll = ud.getUserAll();
            request.setAttribute("all", userAll);
            request.getRequestDispatcher("showAll.jsp").forward(request, response);
        }
    }
    
    1. 在servlet下创建updateServlet用来更新用户信息(在此仅仅根据id来更新用户姓名,逻辑性很弱
    package servlet;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.text.ParseException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import dao.UserDao;
    import dao.UserDaoImplement;
    import entity.MyUser;
    
    public class updateServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doPost(request, response);
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            String id = request.getParameter("id");
    
            String name = request.getParameter("name"); //获取jsp页面传过来的参数
    
            UserDao ud = new UserDaoImplement();
    
            if(ud.update(name, id)){
                request.getRequestDispatcher("/addUpdateDeleteSuccess.jsp").forward(request, response);
            }else{
                response.sendRedirect("addUpdateDeleteFail.jsp");
            }
        }
    }
    

    补充:在servlet下创建deleteServlet用来删除用户信息

    package servlet;
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import dao.UserDao;
    import dao.UserDaoImplement;
    
    public class deleteServlet extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doPost(request, response);
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            String id = request.getParameter("id");
    
            UserDao ud = new UserDaoImplement();
    
            if (ud.delete(id)) {
                request.getRequestDispatcher("addUpdateDeleteSuccess.jsp").forward(request, response);
            } else {
                response.sendRedirect("addUpdateDeleteFail.jsp");
            }
        }
    }
    
    
    1. 新建各种jsp页面

    login.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <html>
    <head>
        <title>登录注册页面</title>
    </head>
    <body >
    
    <form action="loginServlet"  method="post"  style="padding-top:-700px;">
        用户名:<input type="text" name="name"value=""><br><br>
        密码:  <input type="password" name="password"value=""><br><br>
        <input type="submit"value="登录"name="login"><input type="reset"value="重置"><br>
    </form>
    
    <form action="register.jsp">
        <input type="submit"value="新用户注册">
    </form>
    
    </body>
    </html>
    
    

    success.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <%
        String path = request.getContextPath();
        String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
        <title>My JSP 'success.jsp' starting page</title>
    </head>
    <body>
    <br>
    <a href="showAllServlet">查看所有用户</a>
    </body>
    </html>
    
    

    register.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <%
        String path = request.getContextPath();
        String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
        <title>My JSP  starting page</title>
    </head>
    <body >
    <form action="registerServlet"method="post" style="padding-top:-700px;">
        输入姓名:<input name="name" type="text"><br><br>
        输入密码:<input name="password" type="password"><br><br>
        输入id:<input name="id" type="text" ><br><br>
    
        <input type="reset"value="重置"><input type="submit"value="注册">
    </form>
    </body>
    </html>
    

    showAll.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%@ page import="com.entity.MyUser" %>
    <%@ page import="java.util.ArrayList" %>
    <%@ page import="com.dao.UserDao" %>
    <%@ page import="com.dao.UserDaoImplement" %>
    <%@ page import="java.lang.ref.ReferenceQueue" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>所有用户页面</title>
      </head>
    
    <body>
    
    <!--以下两段代码放在body中不要放在<html>之外-->
    <%
    String path=request.getContextPath();
    String basepath=request.getScheme()+"://"+ request.getServerName()+":"+request.getServerPort()+"/";
    %>
    <!-- 使用from提交数据,不能在不刷新页面的情况下直接在当前页面显示处理过的后台数据-->
     <c:forEach var="U" items="${requestScope.all}"  >
          <form action="updateServlet" method="post">
           <tr>
    	       <td><input type="text" value="${U.name}" name="name" ></td>
    	       <td><input type="text" value="${U.password}" name="password"></td>
                <td><input type="text" value="${U.id}" name="id"></td>
               <td><a href="deleteServlet?id=${U.id}">删除</a> <input type="submit" value="更新"/></td>
    	   </tr>
        </form>
        </c:forEach>
    </body>
    </html>
    

    addUpdateDeleteFail.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>addUpdatedDeleteFail</title>
    </head>
    <body>
    <p>addUpdateDeleteFail</p>
    </body>
    </html>
    

    addUpdateDeleteSuccess.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>addUpdateDeleteSuccess</title>
    </head>
    <body>
    <a href="showAllServlet">查看所有用户</a>
    </body>
    </html>
    
    

    操作截图

    1. 开启Tomcat,运行login.jsp,展示首页
      在这里插入图片描述

    2. 输入名字001与密码123,登录成功进入loginServlet,点击查看所有用户,显示用户信息
      在这里插入图片描述
      在这里插入图片描述

    3. 点击删除,若是删除成功则返回所有用户列表,否则返回addUpdateDelete.jsp(这里不展示删除具体的例子)

    4. 在首页点击注册,进入注册页面,注册007,注册完成会返回登录页面
      在这里插入图片描述

    遇到的问题以及解决方式

    问题1
    在showAll.jsp页面中显示了所有数据库的数据,但是删除或者更改其中的一个数据,再想返回修改数据之后的当前页面,就会出现错误。

    问题症结所在:jsp页面回显数据

    分析:前端提交数据,主要有两种方式。from表单与ajax异步提交。两种方式都可以提交数据到后台。但是想让后台数据返回当前页面显示的话,在不刷新整个页面的前提下,就需要使用ajax,因为ajax可以实现异步刷新

    解决方式:在此转换了一个思路。删除或者更新之后,先跳转到addUpdateDeleteSuccess.jsp,这个jsp界面有个按钮链接可以跳转到showAll.jsp界面,然后再显示所有用户的信息(其实使用ajax解决也是ok的)

    问题2:端口1099被占用
    解决方式:
    1) 在mac终端输入lsof -i tcp:1099,查看是哪个进程占用1099
    2) 知道是进程80049占用
    输入sudo kill -9 80049,即可解决问题
    在这里插入图片描述
    问题3
    java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
    解决:
    将数据库连接的jar文件导入到工程的web/WEB-INF/lib中(查询连接https://blog.csdn.net/mayuko2012/article/details/72971997)

    问题4:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column…

    分析:出现这个异常的很大可能性是 数据库是没有问题的!关键原因是:你从传过来的参数是String类型的,我们在操作数据库时String类型的参数必须要用’ ‘把参数引起来才能传递并接收! 例如rs=stmt.executeQuery(“select * from userinfo where userid = '”+ID+"’");ID是String类型,在进行数据库操作时,千万不要漏了两边的单引号,切记 !!!常错点!!!

    问题5:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException异常,
    解决:一般都是自己的sql语句写错了(仔细查找错误)。

    问题6:org.apache.jasper.JasperException: javax.el.ELException: Failed to parse the expression [${}]
    分析:没有jstl标签库
    操作:在lib文件夹添加相关的jar。文章开头已给出。

    感想

    • 报错的信息,可以直接粘贴,google一下,很多问题都可以找得到答案。
    • google问题时候,比较考验自己的筛选能力。很多博文写的真的是只有自己能看懂,所以我在找错的时候花了很多的时间
    • 有条件一定要翻墙google,百度真的是会浪费你的时间。买个一年的服务器也就是百来十块钱,但是自己的时间一定是可以节省很多的。
    • 多上github,StackOverflow,多用google。
    • 有一个bug我改了三天,都变佛系了。改了一天没结果,我就第三天再继续刚。
    • 有个27寸的显示器真的能让你多坐在座位上打码
    • 初级选手的话,数据库的表尽量设计得简单,不然很麻烦
    • 打码更多需要的是耐心与坚持
    展开全文
  • javaweb学生管理系统 第一次总结

    万次阅读 热门讨论 2017-10-19 18:28:34
    JavaWeb 学生管理系统 第一次总结
  • Javaweb 后端框架总结

    万次阅读 2018-11-22 15:26:01
    REST方法     ... IOC(Inversion of Controller)-面向对象的一个准则,对象的控制(创建和管理)由容器或者框架来实现,而不是开发者直接调用,开发者只需要实现接口或者放入自己的类就可以 ...
  • 【狂神说JAVA】JavaWeb

    2020-11-13 17:05:47
    Java Web 1、基本概念 1.1、前言 web开发: web,网页的意思 , www.baidu.com 静态web html,css 提供给所有人看的数据始终不会发生变化! 动态web 淘宝,几乎是所有的网站; 提供给所有人看的数据始终会发生...
  • java web开发(一) 环境搭建

    万次阅读 多人点赞 2016-05-17 15:34:36
    一直都在做App开发,但是对java web方面的了解比较少,最近有时间,所以自己就寻思动手从零开始搭建一个java web项目。该项目主要是给app,提供接口服务,简称项目为‘mserver’。好了,接下来,我们就开始简单的...
  • JavaWeb快速入门(一)——新建JavaWeb项目

    万次阅读 多人点赞 2018-07-04 20:01:33
    今天是暑期实训的第三天,上午继续昨天未讲完的任务java,比如:java的异常处理、java的集合等其它java常用知识,具体讲解链接如下。下午开始将JavaWeb服务器端程序开发,包含:处理请求和展示返回回来的数据。其中...
  • Java WEB开发基础知识

    万次阅读 多人点赞 2018-05-30 20:48:21
    一、WEB应用程序B/S ( browser/server ,浏览器/服务器)架构基于HTTP传输协议(超文本传输协议,回忆HTML的名字:超文本标记语言)WEB程序必须要运行在web容器上,如Tomcat /Jboss/WebLogic等二、HTTP协议HTTP使用...
  • 搭建一个完整的javaweb项目

    万次阅读 多人点赞 2018-08-25 21:54:07
    转:https://blog.csdn.net/qq_23994787/article/details/73612870 主要功能有: 涉及到的知识点有: 1.用户注册 1.JDBC  2.用户登录 ...
  • JavaWeb程序设计

    万人学习 2015-05-08 18:03:46
    本课程主要讲授JavaWeb开发基础中的Servlet与JSP部分,其特色在于其讲解的过程中,通过当堂编写代码的讲授方式讲解“关键知识点”,这些“关键知识点”可保证学生从始至终都能写出可运行的Web程序。
  • 用户登录注册流程图 老版: 新版: 登陆界面 注册界面 登陆成功界面 LoginServlet ...import java.io.IOException;...import javax.servlet.annotation.WebServlet; import javax.servle...
  • 初级Java Web工程师-1.JavaWeb 简介

    千次阅读 2018-03-11 12:18:23
    一、JavaWeb简介JavaWeb也就是J2EE,JavaWeb主要是使用各种Java企业级技术来解决相关web互联网领域的技术总和。而且这些技术有一个标准也就是J2EE规范,J2EE规范是这样定义J2EE组件的:客户端应用程序和applet是运行...
  • 使用Eclipse开发JavaWEB项目前期准备新建server新建Java Web 工程编写Java编写JSP服务器执行jsp 前期准备 自行安装tomcat,注意tomcat和Java版本的匹配 新建server eclipse界面下端有如下Servers菜单 如果...
  • Java WEB 分页实现

    万次阅读 多人点赞 2016-04-16 13:08:26
    Java Web 分页实现设计基于 MySQL 的关键字 limitm,n 从指定下标位置 m 开始返回 n 条记录,实现查询某一页的列表数据;前端控制分页"组件",此处组件是手写的,基本效果是支持跳转首页、尾页、以及展示出的页码,...
  • JavaWeb入门登录注册系统

    万次阅读 多人点赞 2018-07-31 04:37:20
    JavaWeb入门先从登录注册系统开始做起. 我的这个入门教程特别简单大家按步骤做就行一定没有问题的!...2、准备工作就是配置好JAVA运行环境和Tomcat运行环境。 3、建立一个JavaWeb项目,随便在一个项目...
  • 宝塔部署java web项目

    万次阅读 多人点赞 2018-01-29 20:25:59
    宝塔部署javaweb项目完整篇,给想要使用宝塔部署java web项目的人一些参考,觉得不错的可以在下方留言点赞哦,有错误的地方也请大家帮忙指出,发消息给我吧,我好修改。 1.首先,登录宝塔面板(安装就不说了,...
  • java+web项目开发,javaweb开发完整实例源代码

    千次下载 热门讨论 2014-03-20 11:18:14
    深入体验java+web开发,javaweb开发完整实例源代码,里面包含使用说明和注解,共有十个不同类型的项目案例供你学习。
  • Java Web 发展史 (一)

    万次阅读 多人点赞 2019-03-24 11:25:52
    一、原起 唉,说来惭愧,本来是想整理一下SpringBoot相关的知识,顺便结合书和网上的资料写一套完整的东西来作为以后复习、供大家借鉴,然后想先写一篇介绍SpringBoot的文章作为开篇,可是要介绍SpringBoot就得好好...
  • Java Web之环境搭建

    万次阅读 多人点赞 2018-07-23 17:12:00
    在之前的工作,一直是以Android为主,前端为辅。经过了几个项目,也基本了解了前后端数据交互到底是怎么回事儿。 但是在做项目的过程中经常有这个问题,项目初期需求定稿开始开发工作期间,服务端的同事需要搭建...
  • 教务管理系统JavaWeb项目

    万次阅读 多人点赞 2018-03-25 16:35:06
    刚学完javaweb,做个项目练手与巩固所学的知识,同时分享自己写的这个教务管理系统,同样也是为自己记下笔记。为以后复习有帮助。该系统没有用到框架的知识,一共花了7天写出来。所以非常适合javaweb初学者教务管理...
  • 为什么创建的javaweb项目没有web.xml? 如何在已经创建好的项目中增加 web.xml 创建一个javaweb项目流程 右键选择New->Dynamic Web Project 下一步 下一步 下一步 注意:上图红色框不勾选,创建的...
  • java web购物车案例的实现

    万次阅读 多人点赞 2019-08-22 15:23:42
    废话不多说,在这里做的是一个图书购物车简单的小系统。 运行结果部分图片显示: 所以需要创建一个实体类,其中应该包括一个书本的所有...接着就是Java web的三层模型,分别是Dao Service Servlet在这里做的都是模...
  • Java Web技术总结

    千次阅读 2018-06-29 18:09:36
    Java Web技术与Spring源码总结 这篇总结主要是基于我之前两个系列的文章而来。主要是把重要的知识点用自己的话说了一遍,可能会有一些错误,还望见谅和指点。谢谢 更多详细内容可以查看我的专栏文章: JavaWeb...
  • Java Web学习笔记(B站 狂神说Java

    千次阅读 多人点赞 2020-05-17 15:43:27
    JavaWeb 5 Maven 5.4 阿里云镜像 maven文件夹下conf/settings.xml <mirror> <id>nexus-aliyun</id> <mirrorOf>central</mirrorOf> <name>Nexus aliyun</name> &...
  • Java web实习总结

    万次阅读 2017-09-04 14:19:25
    Java web 实习总结
  • Java web 图书管理系统

    万次阅读 多人点赞 2019-07-30 14:57:00
    本系统由java+sevlet+mysql+eclipse实现的Java web图书管理系统,具有增删改查以及导出Excel表格的功能,需要源码或者需要定制类似的Java /Java web/ ssm/spring boot小型系统,如果需要讲解项目、远程部署,可以加...
  • JavaWEB商城项目源码(有后台)

    万次阅读 多人点赞 2018-09-20 18:06:19
    前台页面 1.商城首页(搜索功能:使用的是JQquery实现,模糊查询显示商品列表,单击商品名称,自动填充搜索框) 2.商城分类页面(分类列表这里只做了6个是利用Ajax从数据库读取的,如有需要自行添加) ...
  • Javaweb商城项目实战篇

    千人学习 2019-07-24 22:23:36
    本门课程核心围绕javaweb实战网上商城项目作为基础,其中讲解数据结构的搭建以及项目细节的实战和项目上线流程等内容。课程主要包括: 第1章 Javaweb项目实战——搭建和登录注册模块 第2章 Javaweb项目实战...

空空如也

1 2 3 4 5 ... 20
收藏数 1,714,008
精华内容 685,603
关键字:

java web

java 订阅