JavaWeb基础
JavaWeb
1、简介
在Sun的Java Servlet规范中,对Java Web应用作了这样定义:“Java Web应用由一组Servlet、HTML页、类、以及其它可以被绑定的资源构成。它可以在各种供应商提供的实现Servlet规范的 Servlet容器 中运行。”
Java Web应用中可以包含Servlet、JSP、实用类、静态文档如HTML、图片等描述Web应用的信息(web.xml)
- 静态web资源(如html 页面):指web页面中供人们浏览的数据始终是不变。
- 动态web资源:指web页面中供人们浏览的数据是由程序产生的,不同时间点访问web页面看到的内容各不相同。

2、Servlet
2.1 Servlet简介
Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。我们把把实现了Servlet接口的Java程序叫做,Servlet。
Servlet 在 Web 应用程序中的位置:

2.2 创建第一Servlet程序
Serlvet接口Sun公司有两个默认的实现类:HttpServlet,GenericServlet
HttpServlet抽象类
HttpServlet抽象类是继承于GenericServlet抽象类而来的。使用HttpServlet抽象类时,还需要借助分别代表Servlet请求和Servlet响应的HttpServletRequest和HttpServletResponse对象。
HttpServlet抽象类覆盖了GenericServlet抽象类中的Service( )方法,并且添加了一个自己独有的Service(HttpServletRequest request,HttpServletResponse方法。

编写一个Servlet程序

下面是具体的实现:
- 实现Servlet接口:
public class HelloServlet extends HttpServlet { //继承与HttpServlet,拥有Servlet的所有方法
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
PrintWriter writer = resp.getWriter(); //响应流
writer.print("<h1>Hello World</h1>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- Servlet映射:每一个Servlet都需要有一个注册和映射,才可以连接到服务器上。
<servlet>
<!--给Servlet取名,取什么都可以-->
<servlet-name>helloservlet</servlet-name>
<!--Servlet的全限类名,即Servlet在项目中的位置-->
<servlet-class>com.vxzx.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<!--取与上面name一样的名字-->
<servlet-name>helloservlet</servlet-name>
<!--在浏览器中通过该url找到Servlet,即url地址 记得前面加 "/"-->
<url-pattern>/servlet</url-pattern>
</servlet-mapping>
- 启动Tomcat,开始测试;
注意:
-
默认路径;(
/* ) -
一个Servlet可以指定一个映射路径;
-
一个Servlet可以指定多个映射路径;
-
一个Servlet可以指定通用映射路径;(例如:使用url/* 代表url路径后的所有路径都可以访问)
2.3 Servlet原理
- 客户端发送请求至服务器
- 服务器启动并调用Servlet,Servlet根据客户端请求生成响应内容并将其传给服务器
- 服务器将响应返回客户端

2.3.1 Servlet生命周期
一般来说,Servlet经历了3个时期:出生:init、运行:service、死亡:destroy;
- .init( ),当Servlet第一次被请求时,Servlet容器就会开始调用这个方法来初始化一个Servlet对象出来,但是这个方法在后续请求中不会在被Servlet容器调用,该方法只会执行一次。
- service( )方法,每当请求Servlet时,Servlet容器就会调用这个方法。该方法在Servlet的周期内可以无限次调用。
- destory,当要销毁Servlet时,Servlet容器就会调用这个方法。在卸载应用程序或者关闭Servlet容器时,就会发生这种情况,一般在这个方法中会写一些清除代码。
public class ServletDate extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("Servlet正在初始化");
}
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("Servlet正在提供服务");
}
@Override
public void destroy() {
System.out.println("Servlet正在销毁");
}
}
2.4 ServletContext
web容器在启动的时候,它会为每个web程序都创建一个且只有一个对应的ServletContext对象,它代表了当前的web应用;
有了ServletContext对象,就可以共享从应用程序中的所有资料处访问到的信息,并且可以动态注册Web对象。前者将对象保存在ServletContext中的一个内部Map中。****保存在ServletContext中的对象被称作属性。
2.4.1 共享数据:
在该Servlet中保存数据,可以在另外一个Servlet中拿到数据:getServletContext()
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("hello servlet");
//this.getServletContext() Servlet上下文
ServletContext context = this.getServletContext();
//自定义需要传输的数据:
String username = "vxzx";
//将一个数据保存在ServletContext中,名字为username,值为:username对象.
context.setAttribute("username",username);
}
}
public class Get extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String username = (String)context.getAttribute("username");
resp.setContentType("text/html;charset=utf-8");
PrintWriter os = resp.getWriter();
os.print("<h1>" + username + "</h1>");
}
接下来在web.xml中配置注册Servlet、映射:
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.vxzx.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>get</servlet-name>
<servlet-class>com.vxzx.Get</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>get</servlet-name>
<url-pattern>/get</url-pattern>
</servlet-mapping>
测试结果:
在 /get 界面也可以显示出 /hello里面的数据(username);
2.4.2 获取初始化参数
在Servlet中还可以获取web.xml里面定义好的初始化数据;getInitParameter()
web.xml中定义初始化数据:
<!-- 配置一些web的初始化参数:-->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306</param-value>
</context-param>
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
PrintWriter os = resp.getWriter();
os.print(url);
}
配置xml文件中的Servlet;
测试结果:显示 ---> jdbc:mysql://localhost:3306
2.4.3 请求转发
在Servlet中还可以其他Servlet的数据请求转发到本页面来;getRequestDispatcher()
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
//转发的请求路径:
RequestDispatcher rd = context.getRequestDispatcher("/url");
//调用forword实现请求转发:
rd.forward(req, resp);
//请求响应的将会是上面demo03的数据
}
配置xml文件中的Servlet;
测试结果:显示 ---> jdbc:mysql://localhost:3306
注意:使用请求转发,该url是不会发生任何改变的。
2.4.4 读取资源文件
在Servlet中还可以读取配置文件的资源(例如:properties);
1、创建定义配置文件 db.properties:
username=root
password=123456
2、读取properties资源文件:
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//读取target里面的properties的数据:
//需要一个文件流读取数据:
InputStream is = this.getServletContext().getResourceAsStream("/WEBINF/classes/db.properties");
Properties prop = new Properties();
prop.load(is); //将获取到的数据流加载到prop中
//获取properties里面的数据:
String user = prop.getProperty("uername");
String pwd = prop.getProperty("password");
//输出数据:
PrintWriter os = resp.getWriter();
os.print(user + ":" + pwd);
}
配置xml文件中的Servlet;
测试结果:显示 ---> root:123456
2.5 HttpServletResponse
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse;

- 获取客户端请求的信息,使用HttpServletRequest;
- 响应给客户端一些信息,使用HttpServletResponse;
2.5.1 浏览器中跳转下载文件
具体步骤:
- 获取下载文件的地址;
- 设置下载文件名;
- 设置浏览器支持下载我们需要下载的文件;
- 获取输入流;inputstream
- 设置缓冲区存放输入流获取到的数据;
- 通过请求得到OutputStream将缓冲区中的数据输出到客户端!
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String realPath = "G:\\StudyData\\java\\JavaWeb\\java-02-maven\\response\\target\\classes\\林.jpg";
System.out.println("下载文件的路径:" + realPath);
String FileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
resp.setHeader("Content-Disposition","attachment; filename=" +URLEncoder.encode(FileName,"utf-8"));
FileInputStream fis = new FileInputStream(realPath);
int len = 0;
byte[] buff = new byte[1024];
ServletOutputStream out = resp.getOutputStream();
while ((len = fis.read(buff)) != -1){
out.write(buff,0,len);
}
out.close();
fis.close();
}
配置web.xml里面的servlet;
2.5.2 实现重定向
B一个web资源收到客户端A请求后,B他会通知A客户端去访问另外一个web资源C,这个过程叫重定向
常见场景:
- 用户登录

测试代码:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*本质:
resp.setHeader("Location","/res/down");
resp.setStatus(302);
* */
resp.sendRedirect("/res/down"); //重定向
System.out.println("重定向成功!");
}
2.5.3 简单实现登录重定向
html界面:
<%--设置页面编码,防止乱码--%>
<%@ page contentType="text/html; charset=utf-8"%>
<%--${pageContext.request.contextPath}指当前项目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
用户名:<input type="text" name="username"/> <br/>
密码:<input type="password" name="password"/> <br/>
<input type="submit" value="登陆"/>
</form>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入请求!");
//处理请求:
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("username:" + username + "\n" + "password:" + password);
//重定向,无论什么类型的,都可以重定向,页面的需要加上后缀
resp.sendRedirect("/res/req.jsp");
}
最后记得在web.xml配置servlet。
2.6 HttpServletRequest
HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息;
2.6.1 获取参数和请求转发
其中,获取参数的方法:getParameter()、getParameterValues()
下面是一个简易的注册页面的代码实现:
html页面:
<div align="center">
<form action="${pageContext.request.contextPath}/login" method="post">
用户名: <input type="text" name="username"/> <br/>
密 码: <input type="password" name="password"/><br/>
性别:
<input type="radio" name="sex" value="男">男
<input type="radio" name="sex" value="女">女 <br/>
爱好:
<input type="checkbox" name="hobby" value="篮球">篮球
<input type="checkbox" name="hobby" value="足球">足球
<input type="checkbox" name="hobby" value="跑步">跑步<br/>
<input type="submit" value="登陆"/>
</form>
</div>
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决后台接收数据乱码问题:
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
String sex = req.getParameter("sex");
String[] hobbies = req.getParameterValues("hobby");
System.out.println(username);
System.out.println(password);
System.out.println(sex);
// System.out.println(Arrays.toString(hobbies));
for (int i = 0; i < hobbies.length; i++) {
System.out.print(hobbies[i] + ";");
}
System.out.println();
//重定向转发:
// resp.sendRedirect("/req/Success.jsp");
//通过请求转发:到自定义页面Success.jsp
req.getRequestDispatcher("/Success.jsp").forward(req,resp);
}
3、Cookie & Session
3.1 会话机制
Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
例如:用户在浏览器打开多个链接,访问多个资源,最后关闭浏览器,这过程就叫做会话。
- cookie:客户端技术(请求,响应);
- 服务端给客户端一个数据包,客户端下次登陆直接带上这个数据包就可以直接登陆。
- session:服务器技术,可以保存用户会话信息,可以将信息、数据保存在session中;
- 服务器会登记你登陆过的信息,下次就会自动匹配到你的信息。
我们常见的使用场景:网站登陆后,下次不需要再输入账号和密码登陆,可直接访问。
3.2 Cookie
通过上面,我们已经知道Cookie通过在客户端记录信息确定用户身份,他的作用大概也就是保存在客户端,用来记录用户身份信息等。。。。
Cookie的特点:
- 每一个cookie文件大小:4kb , 如果超过4kb浏览器不识别
- 一个web站点(web项目):发送20个
- 一个浏览器保存总大小:300个
- cookie 不安全,可能泄露用户信息。浏览器支持禁用cookie操作
- 默认情况生命周期:与浏览器会话一样,当浏览器关闭时cookie销毁的
创建一个Cookie程序:
1、从请求中获取一个Cookie信息:
//Cookie,服务器从客户端请求得到Cookie:
Cookie[] cookies = request.getCookies(); //返回数组,Cookie有多个
//判断Cookie是否存在:
if(cookies != null){
for(i=0; i<cookies.lenght; i++){
Cookie cookie = cookies[i];
//获取cookie的名字:
if(cookie.getName().equal("name")){
//获取cookie的值:
String value = cookie.getValue();
response.getWriter.writer(value);
}
}
}else{
System.out.println("第一次访问:");
}
2、服务器响应给客户端cookie:
//服务器给客户端响应一个Cookie:
Cookie cookie = new Cookie("name","VXZX"); //以键值对的方式存放内容
cookie.setMaxAge(24*60*60); //设置cookie存在的时间
response.add(cookie); //发送回浏览器端
注意:cookie创建后不能再插入其他的键值对,但是可以对其进行修改,cookie.setvalue(key,value)。
以下是完整的程序:
//第一次访问该web的时间:
public class CookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决中文乱码问题:
resp.setContentType("text/html");
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
Cookie[] cookies = req.getCookies();
if (cookies != null){
out.write("上次访问的时间是:");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
if (cookie.getName().equals("LoginTime")){
String value = cookie.getValue();
Long LoginTime = Long.parseLong(value);
Date date = new Date(LoginTime);
out.write(date.toLocaleString());
}
}
}else {
out.write("第一次访问:");
}
Cookie cookie = new Cookie("LoginTime",String.valueOf(System.currentTimeMillis()));
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);
}
}
最后,记得需要再web.xml中配置servlet;该步骤与上面一样。
3、手动清除cookie:
上面已经讲过,使用cookie.setMaxAge() 可以设置cookie存在的时间,那么我们就可以用它来清除已存在的cookie。
- 不设置有效期,关闭浏览器,自动失效;
cookie.setMaxAge()设置有效时间为0,即可手动清除cookie;
//新建一个cookie,该cookie需要与要清除的cookie键值对一模一样:
Cookie cookie = new Cookie("name","VXZX");
cookie.setMaxAge(0);
response.add(cookie);
具体实现:
public class CookieServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie = new Cookie("LoginTime",System.currentTimeMillis() + "");
cookie.setMaxAge(0);
resp.addCookie(cookie);
}
}
如果使用中文出现乱码,我们可以用编码解码的方法来解决乱码的问题:
URLEncoder.encode("中文","utf-8") //编码
URLDecoder.decode(cookie.getValue(),"UTF-8") //解码
3.3 Session***
session的简介:
- 服务器会给每一个用户(浏览器)创建一个Seesion对象;
- 一个Seesion独占一个浏览器,只要浏览器没有关闭,这个Session就存在;
- 用户登录之后,整个网站它都可以访问!--> 保存用户的信息;保存购物车的信息…..
使用场景:
- 保存一个登录用户的信息;
- 购物车信息;
- 在整个网站中经常会使用的数据,我们将它保存在Session中;
创建一个session程序:
//请求获取session:
HttpSession session = request.getSession();
//给session存入数据:(可以存放字符串也可以存放对象)
session.setAttribute("name","vxzx");
session.setAttribute("name1",new Person("姓名","年龄")); //存放一个Person对象
//最后可以再任意页面通过getAttribute()获取到该session中的数据;
具体实现:
1、存放数据到session中:
public class SessionDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//得到session:
HttpSession session = req.getSession();
//给session里面存放数据: --Person()对象需要自己创建--
session.setAttribute("username",new Person("VXZX",11));
//获取session的id:
String id = session.getId();
//判断是否为新创建的session:
if (session.isNew()){
resp.getWriter().write("第一次创建session:" + id);
}else {
resp.getWriter().write("session已存在:" + id);
}
}
}
最后,记得需要再web.xml中配置servlet;
2、获取session中存放的数据:
public class SessionDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
HttpSession session = req.getSession();
Person username = (Person) session.getAttribute("username");
resp.getWriter().write(username.toString());
}
}
3、移除session:
我们可以通过自己来控制session的有效时间,来将session移除,节省内存空间。
我们可以使用一些几个方法:
-
session.removeAttribute()将指定值的session移除 -
session.invalidate()将session对象销毁 -
setMaxInactiveInterval(int interval)设置有效时间,单位秒
public class SessionDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
//移除session:
session.removeAttribute("username");
//注销session:
session.invalidate();
}
}
还可以在web.xml中配置session的有效时间:
<!--设置session的失效时间 默认:30分钟-->
<session-config>
<!-- 20分钟后失效:-->
<session-timeout>20</session-timeout>
</session-config>
*Session和cookie的区别:
- Cookie是把用户的数据写给用户的浏览器,浏览器保存 (可以保存多个)
- Session把用户的数据写到用户独占Session中,服务器端保存 (保存重要的信息,减少服务器资源的浪费)
- Session对象由服务创建;
总结:
- cookie是一种在客户端记录用户信息的技术,因为http协议是无状态的,为了解决这个问题而产生了 cookie。记录用户名等一些应用。。。。
- session是一种在服务端记录用户信息的技术,一般session用来在服务器端共享数据。
4、JSP
4.1 JSP简介
Java Server Pages : Java服务器端页面,也和Servlet一样,用于动态Web技术!可以再页面中嵌入JAVA代码,为用户提供动态数据;
4.2 JSP的执行原理
JSP的核心其实是将我们编写的JSP页面,会自动编译成.java文件,而这个.java文件中有继承了HttpServlet类的所有方法;所以浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet!

4.2.1 JSP的生命周期
- 初始化阶段:加载与JSP对应的servlet类,创建其实例,并调用它的初始化方法。
- 执行阶段:调用与JSP对应的servlet实例的服务方法。
- 销毁阶段:用与JSP对应的servlet实例的销毁方法,然后销毁servlet实例。JSP
//初始化
public void _jspInit() {
System.out.println("正在初始化JSP");
}
//JSPService
public void _jspService(.HttpServletRequest request,HttpServletResponse response) {
System.out.println("正在加载JSP服务");
}
//销毁
public void _jspDestroy() {
System.out.println("正在销毁JSP");
}
4.2.2 JSP中常见的内置对象
final javax.servlet.jsp.PageContext pageContext; //页面上下文
javax.servlet.http.HttpSession session = null; //session
final javax.servlet.ServletContext application; //applicationContext
final javax.servlet.ServletConfig config; //config
javax.servlet.jsp.JspWriter out = null; //out
final java.lang.Object page = this; //page:当前
HttpServletRequest request //请求
HttpServletResponse response //响应
4.2 JSP基础语法
4.2.1 JSP表达式(<%= %>)
<%--JSP表达式
作用:用来将程序的输出,输出到客户端
<%= 变量或者表达式%>
使用该表达式,java语言式子后面不用加上;
--%>
<%=new Date()%>
测试代码:
<body>
<% int i = 10;%>
<% System.out.println(i);%>
<% out.print(i); %>
<h1>这是一个JSP页面</h1>
<% out.print(new Date());%>
<%-- JSP表达式,将程序输出到客户端 --%>
<%=new Date()%>
</body>
4.2.2 JSP脚本片段(<% %>)
<%--jsp脚本片段--%>
<%
int sum = 0;
for (int i = 1; i <=100 ; i++) {
sum+=i;
}
out.println("<h1>Sum="+sum+"</h1>");
%>
测试代码:
<body>
<%--JSP脚本片段--->在代码嵌入HTML元素: --%>
<%
for (int j = 1; j <= 5; j++) {
%>
<h1>JSP页面! <%=j%></h1>
<% }%>
</body>
4.2.3 JSP声明(<%! %>)
<%!
static {
System.out.println("Loading Servlet!");
}
private int globalvar = 0;
public void speak(){
System.out.println("use this is method!");
}
%>
<% this.speak();%>
JSP声明:会被编译到作用域更高的JSP生成Java的类中!其他的,就会被生成到_jspService方法中!
4.2.4 JSP指令
<%@page args.... %> 可以使页面跳转等操作
<%@include file=""%> 可以把其他页面包含进来本页面等操作
可以在web.xml中配置自定义错误的页面,当发生错误时,就会跳转到自定义的页面。
<!-- 自定义错误页面: -->
<error-page>
<error-code>404</error-code>
<location>/error/error02.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/error01.jsp</location>
</error-page>
设置好错误页面之后,只要网站发生404错误或者500错误就会跳转到error目录下的页面。
测试代码:
<%-- 使用JSP指令,将两个页面合二为一: --%>
<%@ include file="header.jsp"%>
<h1>MAIN主页面</h1>
<%@ include file="bottom.jsp"%>
<%-- 使用JSP标签,将两个页面拼接在一起,本质上还是三个页面: --%>
<jsp:include page="header.jsp"></jsp:include>
<h1>MAIN主页面</h1>
<jsp:include page="bottom.jsp"></jsp:include>
4.3 JSP九大内置对象
- PageContext: 存数据
- Request: 存数据
- Response:
- Session: 存数据
- Application [ServletContext] 存数据
- config [servletConfig]
- out
- page
- exception
<%--内置对象:--%>
<body>
<%
pageContext.setAttribute("data1","单车"); //保存的数据再一个页面中有效
request.setAttribute("data2","摩托车"); //数据再一次请求中有效
session.setAttribute("data3","汽车"); //数据再一次会话中有效,从打开浏览器到关闭
application.setAttribute("data4","火车"); //数据只在服务器中有效,从打开服务器到关闭
%>
<%
String data1 = (String) pageContext.findAttribute("data1");
String data2 = (String) pageContext.findAttribute("data2");
String data3 = (String) pageContext.findAttribute("data3");
String data4 = (String) pageContext.findAttribute("data4");
String data5 = (String) pageContext.findAttribute("data5");
%>
<%--使用EL表达式输出: ${} --%>
<h1>${data1}</h1>
<h1>${data2}</h1>
<h1>${data3}</h1>
<h1>${data4}</h1>
<h1>${data5}</h1>
<h1><%=data5%></h1> <%--会在页面显示出null--%>
</body>
request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻,用户看完没用的!
session:客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如:购物车;
application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如:聊天数据。
4.4 JSP标签、JSTL标签、EL表达式
首先,需要先配置jar包:
<!--JSTL表达式依赖 -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!--standard标签库 -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
-
EL表达式: ${}
- 获取数据
- 执行运算
- 获取web开发的常用对象
-
JSP标签
<%-- JSP标签: 拼接页面,本质还是三个页面 --%>
<jsp:include page="header.jsp"></jsp:include>
<h1>MAIN主页面</h1>
<jsp:include page="bottom.jsp"></jsp:include>
--------------------------------------------------------------------
<%--设置参数,再jsptag2中取出:--%>
<jsp:forward page="jsptag2.jsp">
<jsp:param name="username" value="vxzx"/>
<jsp:param name="passwd" value="123456"/>
</jsp:forward>
--------------------------------------------------------------------
<%--取出jsptag的参数:--%>
<h1>This is jsptag2!</h1>
用户名:<%=request.getParameter("username")%>
密码:<%=request.getParameter("passwd")%>
- JSTL标签
核心标签 (掌握部分):

首先需要引入核心标签库的语法:
<%--引入JSTL核心标签库:--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
c:if
<h3>if测试:</h3>
<form action="coreif.jsp" method="get">
<%-- EL表达式获取表单中的数据: *** param.参数名 *** --%>
<input type="text" name="username" value="${param.username}">
<input type="submit" value="提交">
</form>
<%--判断提交名字是管理员,则提交成功:--%>
<c:if test="${param.username =='admin'}" var="isAdmin">
<c:out value="欢迎管理员"/>
</c:if>
<c:out value="${isAdmin}"/>
</body>
EL表达式获取表单中的数据------> ${param.参数名}
c:forEach
<body>
<%
ArrayList<String> list = new ArrayList<>();
list.add(0,"张三");
list.add(1,"李四");
list.add(2,"王五");
list.add(3,"赵六");
request.setAttribute("list",list);
%>
<c:forEach var="list" items="${list}" begin="0" end="4" step="3">
<h1><c:out value="${list}"/></h1><br>
</c:forEach>
</body>
var , 每一次遍历出来的变量
items, 要遍历的对象
begin, 哪里开始
end, 到哪里
step, 步长
5、JavaBean
JavaBean 是一种JAVA语言写成的*可重用*组件**。为写成JavaBean,类必须是*具体的和公共的*,并且具有*无参数的**构造器*。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,*set和get方法获取*。
JavaBean的特定写法:
- 需要拥有一个无参构造器:
- 需要有get和set方法;
- 属性必须私有化;
一般用来和数据库的字段做映射。 ORM
ORM :对象关系映射:
- 表--->类
- 字段-->属性
- 行记录---->对象
先封装一个people类:
//实体类一般都与数据库中的表结构--对应:
public class People {
private int id;
private int age;
private String name;
private String address;
public People() {
}
public People(int id, int age, String name, String address) {
this.id = id;
this.age = age;
this.name = name;
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
<jsp:useBean id="people" class="com.vxzx.servlet.People" scope="page"/>
<!-- <jsp:useBean id="bean 的名字(id)" class="bean 编译的类" scope="bean 的作用域" typeSpec/>
<jsp:setProperty name="bean 的 id" property="属性名" value="value"/>
<jsp:getProperty name="bean 的 id" property="属性名"/>
-->
<body>
<%
// People people = new People();
//等价于下面的jsp:useBean语句;
// people.setId(1);
// people.setAddress("广州");
// people.setAge(18);
// people.setName("VXZ");
//
// people.getId();
// people.getAddress();
// people.getAge();
// people.getName();
%>
<jsp:useBean id="people" class="com.vxzx.servlet.People" scope="page"/>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="address" value="广州"/>
<jsp:setProperty name="people" property="age" value="18"/>
<jsp:setProperty name="people" property="name" value="VXZ"/>
id号:<jsp:getProperty name="people" property="id"/>
地址:<jsp:getProperty name="people" property="address"/>
年龄:<jsp:getProperty name="people" property="age"/>
姓名:<jsp:getProperty name="people" property="name"/>
</body>
6、MVC三层架构

Model
- 业务处理 :业务逻辑(Service)
- 数据持久层:CRUD (Dao)
View
- 展示数据
- 提供链接发起Servlet请求 (a,form,img…)
Controller (Servlet)
- 接收用户的请求 :(req:请求参数、Session信息….)
- 交给业务层处理对应的代码
- 控制视图的跳转
登录--->接收用户的登录请求--->处理用户的请求(获取用户登录的参数,username,password)---->交给业务层处理登录业务(判断用户名密码是否正确:事务)--->Dao层查询用户名和密码是否正确-->数据库
7、Filter**
Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。

实现Filter接口,重写对应的方法即可:
//Chain : 链
/*
1. 过滤中的所有代码,在过滤特定请求的时候都会执行
2. 必须要让过滤器继续同行
chain.doFilter(request,response);
*/
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("Filter开启服务:");
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;charset=utf-8");
System.out.println("使用chain前:");
filterChain.doFilter(servletRequest,servletResponse); //必须执行,不然会卡在这里不会进行下一步
System.out.println("使用chain后:");
}
此条语句必写,不然不会继续执行下一步:
filterChain.doFilter(request,response);
配置xml:
<!--过滤器配置,具体写法跟servlet差不多:-->
<filter>
<filter-name>UseFilter</filter-name>
<filter-class>com.vxzx.pojo.UseFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UseFilter</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
8、监听器
监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。
//统计网站在线人数 : 统计session
public class OnlineCountListener implements HttpSessionListener {
//创建session监听: 看你的一举一动
//一旦创建Session就会触发一次这个事件!
public void sessionCreated(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
System.out.println(se.getSession().getId());
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if (onlineCount==null){
onlineCount = new Integer(1);
}else {
int count = onlineCount.intValue();
onlineCount = new Integer(count+1);
}
ctx.setAttribute("OnlineCount",onlineCount);
}
//销毁session监听
//一旦销毁Session就会触发一次这个事件!
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if (onlineCount==null){
onlineCount = new Integer(0);
}else {
int count = onlineCount.intValue();
onlineCount = new Integer(count-1);
}
ctx.setAttribute("OnlineCount",onlineCount);
}
/*
Session销毁:
1. 手动销毁 getSession().invalidate();
2. 自动销毁
*/
}
在xml中配置:
<!--注册监听器-->
<listener>
<listener-class>com.kuang.listener.OnlineCountListener</listener-class>
</listener>
9、JDBC(复习)

需要jar包的支持:
- java.sql
- javax.sql
- mysql-conneter-java… 连接驱动(必须要导入)
数据库创建:
CREATE TABLE users(
id INT PRIMARY KEY,
`name` VARCHAR(40),
`password` VARCHAR(40),
email VARCHAR(60),
birthday DATE
);
INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES(1,'张三','123456','zs@qq.com','2000-01-01');
INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES(2,'李四','123456','ls@qq.com','2000-01-01');
INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES(3,'王五','123456','ww@qq.com','2000-01-01');
Maven中导入数据依赖:
<!--mysql的驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
JDBC 固定步骤:
- 加载驱动
- 连接数据库,代表数据库
- 向数据库发送SQL的对象Statement : CRUD
- 编写SQL (根据业务,不同的SQL)
- 执行SQL
- 关闭连接
定义一个properties文件:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/smbms?useUnicode=true&characterEncoding=true&useSSL=true
user=root
password=123456
basedao.java:封装jdbc工具类
public Basedao {
private static driver = null;
private static url = null;
private static user = null;
private static pwd = null;
static {
Properties properties = new Properties();
Inputstream is = Basedao.class.getClassLoader().getResourceAsStream("jdbc.properties");
properties.load(is);
driver = properties.getproperties("driver");
url = properties.getproperties("url");
user = properties.getproperties("user");
pwd = properties.getproperties("password");
}
public Connection getConnection(){
Connection connection = null;
Class.forname(driver);
connection = MangerDriver.getConnection(url,user,pwd);
return connection;
}
public ResultSet execute(Connection connection,String sql,prepareStatement pst,
Object[] params,ResultSet rs){
pst = connection.prepareStatement(sql);
for(int i=0; i<params.length; i++){
pst.setObject(i+1,params[i]);
}
rs = pst.executeQuery();
return rs;
}
public ResultSet execute(Connection connection,String sql,PrepareStatement pst,
Object[] params){
pst = connection.prepareStatement(sql);
for(int i =0;i<params.length;i++){
pst.setObject(i+1,params[i]);
}
int j = pst.executeUpdate();
return j;
}
public void CloseConnection(Connection con,PrepareStatement pst,ResultSet rs){
if(con != null){
con.close();
}
if(pst != null){
pst.close();
}
if(rs != null){
rs.close();
}
}
}

浙公网安备 33010602011771号