一、Servlet简介
Servlet是sun公司提供的一门用于开发动态web资源的技术。
Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:
1) 编写一个Java类,实现servlet接口。
2) 把开发好的Java类部署到web服务器中。
按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet
Servlet运行过程
- web浏览器 发出http请求到web容器。
- web容器首次访问创建目标 Servlet。
- web容器创建request对象和response对象。
- web容器调用servlet方法,Servlet.servlet(request,response)。
- service(req,resp)获取请求信息,并将响应写入响应信息返回给web容器。
- web容器发出Http响应给web浏览器。
servlet实现类
- servlet接口sun公司定义了两个默认实现类,其分别为:GennericServlet、HttpServlet.
- HttpServlet指能够处理Http请求的servlet,它在原有的Servlet接口上添加了一些与Http协议处理方法,它比Servlet接口的功能更为强大。因此开发人员在编写Servlet时,通常应该继承这个类,而避免直接去实现Servlet接口。
- HttpServlet在实现Servlet接口时,覆盖了service方法,该方法体内的代码会自动判断用户的请求方式。如为Get请求,则调用HttpServlet的doGet方法,如为Post请求,则调用doPost方法。因此,开发人员在编写Servlet请求的时候,通常只需要覆盖写doGet或者doPost方法,而不需要去覆盖写service方法。
二、Servlet开发
使用IDEA开发Servlet的准备条件
- 准备 Servlet需要的jar包(使用idea的话,我们可以文件新建一个ServletlJava文件后,通过alt+enter键来进行自动导入jar包,也可以通过新建资源目录lib,导入已有的jar包)
- 新建一个Servlet
- 在Servlet中编写代码
- 配置web.xml中Servlet映射的mapping url
配置web.xml文件的时候遵守一个servlet对应一个servlet-mapping,如下图:
- 启动服务器(Tomcat)
- 访问Servlet编写的页面
response使用
通过response实现请求重定向
请求重定向指:一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向。
应用场景:用户登陆,用户首先访问登录页面,登录成功后,就会跳转到某个页面,这个过程就是一个请求重定向的过程
实现方式:response.sendRedirect(String location),即调用response对象的sendRedirect方法实现请求重定向
sendRedirect内部的实现原理:使用response设置302状态码和设置location响应头实现重定向,
通过响应对象来重定向页面
resp.sendRedirect(“404.jsp”)
servletContext
-
web容器在启动时,它会为每个web应用程序都创建一个对应servletContext对象,它代表当前web应用。
-
多个Servlet通过ServletContexe对象实现数据共享
-
获取web应用的初始化参数,用servletContext实现请求转发
-
利用ServletContext对象读取资源文件
通过servletContext实现数据共享,可以通过this获得servletContext,实现数据的共享,这里通过输出流来进行一个配置文件的读取做一个示例:driver=com.mysql.jdbc.Driver
username=root
password=123456
url=jdbc:mysql://localhost:3306/student
这是一个数据库配置文件的内容
写一个servlet通过io流来进行资源配置文件的读取并将它显示在网页上
package com.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class Servlet1 extends javax.servlet.http.HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {
String realPath = this.getServletContext().getRealPath("/WEB-INF/classes/resources/database.properties");
System.out.println("取得的路径为"+realPath);
Properties properties = new Properties();
FileInputStream fileInputStream = new FileInputStream(realPath);
properties.load(fileInputStream);
String driver = properties.getProperty("driver");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
//写在网页上
response.getWriter().println(driver);
response.getWriter().println(username);
response.getWriter().println(password);
response.getWriter().println(url);
}
}
配置xml文件的servlet映射
<?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">
<servlet>
<servlet-name>Servlet1</servlet-name>
<servlet-class>com.servlet.Servlet1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet1</servlet-name>
<url-pattern>
/svm
</url-pattern>
</servlet-mapping>
</web-app>
三、resquest使用
这里罗列一些简单的resquest对象的方法使用
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RequestDemo01 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//查看request对象的方式
System.out.println(request.getContextPath()); //获得web项目路径
System.out.println(request.getRequestURI()); //请求的URL路径
//Remote 远程
System.out.println(request.getRemoteUser()); //获得远程的用户名
System.out.println(request.getRequestedSessionId()); //获得SessionId;
System.out.println(request.getServletPath()); //请求servlet的url
System.out.println(request.getLocalAddr()); //获得本地地址 防火墙
System.out.println(request.getLocalName()); //获得本地名字
System.out.println(request.getLocalPort()); //获得访问的端口号
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
重点:request对象可以接收前端用户提交的参数
这个的意思就是我们可以通过request对象来将用户在网页表单中填好的数据获取到后台,然后对它进行各种处理。
这个过程我们分为三步:
- 写一个前端注册的页面,在这里注意两个点:
-
表单提交的方式 get /post
-
表单提交的位置=action:服务项目的路径/servlet对应的请求url
<html> <head> <title>注册</title> </head> <body> <%-- JSP的注释 --%> <%-- Form表单 action:代表要提交的路径,表单要提交到哪里 ,可以提交到一个Servlet //提交到Servlet需要,获取到Web项目的路径下的Servlet method: 提交表单的方式 --%> <h1>注册</h1> <form action="${pageContext.request.contextPath}/r2" method="post"> <p>用户名:<input type="text" name="username"></p> <p>密码:<input type="password" name="password"></p> <p> <input type="submit"> <input type="reset"> </p> </form> </body> </html>
- 写一个处理前端提交信息的Servlet
-
接收前端传递的空间信息,request.getParameter (“控件的name”)
import javax.print.attribute.HashPrintRequestAttributeSet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; //处理前端提交过来的数据 public class RequestDemo02 extends HttpServlet { @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 { //通过HttpServletRequest获取前端用户提交的信息 //req.getParameterValues(); 获得前端传递的控件信息,通过控件的name;但是可以接受多个参数的控件,比如(多选框....) //req.getParameter(); 获得前端传递的控件信息,通过控件的name; req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); String username = req.getParameter("username"); String password = req.getParameter("password"); //连接数据库,比较数据库中的信息是否匹配 if (username.equals("admin")&&password.equals("1234567")){ System.out.println("登录成功!"); //跳转到成功页面 }else { System.out.println("登录失败!"); //提示重新注册 } System.out.println(username); System.out.println(password); } }
-
同样一个servlet要对应有一个servlet-mapping的映射
<servlet-mapping> <servlet-name>RequsetDemo02</servlet-name> <url-pattern>/svn1</url-pattern> </servlet-mapping>
设置完毕后打开服务器,就可查看网页信息,提交表单。
request实现请求转发
package com.servlet;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class FormServlet1 extends HttpServlet {
@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 {
//处理乱码
req.setCharacterEncoding("UTF-8");
//处理前端的请求
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("接收到的用户名:"+username+"\n密码:"+password+"\n爱好:");
String[] hobbies = req.getParameterValues("hobby");
for (String hobby : hobbies) {
System.out.println(hobby);
}
//重定向:服务器告诉客户端你应该请求另外一个地址; (地址栏会变)
//resp.sendRedirect("url");
//转发:服务器把这个请求转向另外一个Servlet去处理; (地址栏不会变)
//RequestDispatcher ,需要使用RequestDispatcher来进行处理,我们需要获得这个类
//参数就是他要转发到的页面
/*
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/success.jsp");
requestDispatcher.forward(req,resp);
*/
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}
}
转发和重定向的区别
重定向:服务器告诉客户端,你去请求另外一个地址;客户端行为
-
地址栏会变
-
不能携带参数
转发:服务器自己转发到服务器上的另一个请求; 服务器行为
- 地址栏不会变
- 可以携带参数
四、会话 cookie 、session
基本概念
1) 什么是会话
在Web中,会话表示从浏览器打开某个网站,在网站中进行操作直至关闭浏览器,这一个过程,称之为一个会话。
2) 会话结束的标志
- 客户端关闭
- 服务器关闭
- javaweb将两个会话分为两种
- cookie 客户端记录会话,客户端关闭会话结束
- session 服务端记录会话,服务器关闭会话结束
cookie
构造器 :
Cookie cookie = new Cookie(String name,String value);
Cookie cookie = new Cookie(String name,String value);
Cookie cookie = new Cookie(String name,String value);
服务器响应cookie给客户端
Response.addCookie(Cookie);
Response.addCookie(Cookie);
Response.addCookie(Cookie);
服务查看用户带来的请求是否有cookie
Cookie[] cookies = Request.getCookie();
//可以使用cookie来验证用户是否来过
//判断cookies是否为空,然后遍历即可
Cookie.getName();
Cookie.getValue();
cookie测试用户是否来过,这里通过一个servlet进行测试
package com.westos.serlvet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CookieTest extends HttpServlet {
boolean flag = false;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决乱码问题:
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
//检查请求的人是否带了Cookie
//通过用户的请求,检查它是否有cookie
Cookie[] cookies = request.getCookies();
System.out.println("cookie:"+cookies);
if (flag){//如果flag是真,来过
if (cookies!=null){//你有cookie
for (int i = 0; i < cookies.length ; i++) {
Cookie cookie = cookies[i];
if (cookie.getName().equals("lastLoginTime")){
response.getWriter().println("你上一次来的时间为:"+cookie.getValue());
System.out.println("刷新了cookie");
}
}
}
}else { //如果flag是真,没来过
response.getWriter().println("你是第一次来,还想要会员套餐");
System.out.println("给该用户一个cookie");
}
//建立一个cookie
Cookie cookie = new Cookie("lastLoginTime",System.currentTimeMillis()+"");
//设置cookie保存的时间 //cookie.setMaxAge();
//把这个cookie发给客户端
response.addCookie(cookie);
//response.addCookie(new Cookie("lastLoginTime",System.currentTimeMillis()+""));
flag = true;
}
}
session
只要客户端一旦连接上服务器,服务器就会自动产生Session;
一个连接对应一个session,session可以在一个会话中传递信息;
通过setAttribute设置值。
通过getAttribute获得值。
由服务器端控制,服务器如果重启了,信息就会丢失!
会话注销的方法
-
会话注销方法一:
session.invalidate();//通过代码注销会话
-
会话注销方法二:
< session-config >
< session-timeout>1</ session-timeout>
< /session-config>