Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,主要功能在于交互式地浏览和生成数据,生成动态Web内容。 Servlet是指任何实现了这个Servlet接口的类
核心:Servlet是指实现了Servlet接口的类
继承HttpServlet类(本质是一个Serlvet接口的实现类)
public class Servlet extends HttpServlet {
}
实现Servlet接口
public class MyServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MyServlet extends HttpServlet {
//doPost和doGet对应前端的两种上传方式,这里直接相互调用即可,因为后台的处理逻辑是相同的
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//这里讲一下
//1.resp.getWriter():获取一个响应输出流
//2.println 打印内容
//3. resp.getWriter().println("Hello,World");和resp.getWriter().write("Hello,World");
//的区别,通过源码可以发现 public void print(Object obj) {
// write(String.valueOf(obj));
// } //用Print可以直接将对象,转化为字符串,从而调用Write方法输出
resp.getWriter().println("Hello,World");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>helloservlet-name>
<servlet-class>MyServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
Mapping:建立URl与Class之间的
<servlet>
<servlet-name>helloservlet-name>
<servlet-class>MyServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hello2url-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/*url-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>*.dourl-pattern>
servlet-mapping>
域对象是服务器在内存上创建的存储空间,用于在不同动态资源(servlet)之间传递与共享数据。
public class Servlet01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html");
getServletContext().setAttribute("name","haha");
resp.getWriter().println("储存了name");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
public class Servlet02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = (String) getServletContext().getAttribute("name");
resp.getWriter().println("1:"+name);//1:haha
//移除
getServletContext().removeAttribute("name");
String name2 = (String) getServletContext().getAttribute("name");
resp.getWriter().println("2:"+name2);//2:null
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
getServletContext().getInitParameter(name);//根据指定的参数名获取参数值
getServletContext().getInitParameterNames();//获取所有参数名称列表
在web.xml中配置全局配置参数
<context-param>
<param-name>name1param-name>
<param-value>1param-value>
context-param>
<context-param>
<param-name>name2param-name>
<param-value>2param-value>
context-param>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String para = getServletContext().getInitParameter("name1");
resp.getWriter().println(para);//1
}
设置context-param和init-param的区别
<context-param>
<param-name>contextparam-name>
<param-value>contextValueparam-value>
context-param>
<servlet>
<servlet-name>s1servlet-name>
<servlet-class>Servlet01servlet-class>
<init-param>
<param-name>name1param-name>
<param-value>value1:1param-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>s1servlet-name>
<url-pattern>/s1url-pattern>
servlet-mapping>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name1 = this.getInitParameter("name1");
resp.getWriter().println(name1);//value:1 用this.getInitParameter只能获取指定Servlet的初始化数据
String context =this.getInitParameter("context");
resp.getWriter().println(context);//null
String name2 = getServletContext().getInitParameter("name1");
resp.getWriter().println(name2);// null 用getServletContext().getInitParameter只能获得指定上下文范围内初始化数据
String context2 =getServletContext().getInitParameter("context");
resp.getWriter().println(context2);//context
}
getServletContext().getRealPath(path),根据相对路径获取服务器上资源的绝对路径
getServletContext().getResourceAsStream(path),根据相对路径获取服务器上资源的输入字节流
在Maven项目中,我们把资源文件放在resources下,在打包的时候,会直接放入classes下
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取输入流
InputStream resourceAsStream = getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");// /代表当前项目
Properties prop = new Properties();
prop.load(resourceAsStream);
//输出
resp.getWriter().println(prop.getProperty("username"));//admin
resp.getWriter().println(prop.getProperty("password"));//123456
}
getServletContext().getContextPath();
//获取当前项目名
resp.getWriter().println(getServletContext().getContextPath());// /ServletConfig_war
getServletContext().getRequestDispatcher(“请求的路径”).forward(req,resp);
//请求转发
getServletContext().getRequestDispatcher("/s1").forward(req,resp);
Request即为从客户端产生的请求,主要用于获取从客户端产生的数据
主要以getXX的方法,获取从客户端带来的数据
<html>
<body>
<h2>Loginh2>
<p>${pageContext.request.contextPath}p>
<%--/HttpRequest_war--%>
<form action="${pageContext.request.contextPath}/r1" method="get">
<input type="text" name="username"><br>
<input type="password" name="password"><br>
<input type="submit">
form>
body>
html>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("+++++++++++++++++++++++++++++++");
System.out.println(username);
System.out.println(password);
System.out.println("++++++++++++++++++++++++++++++++");
//下面进行请求转发,将请求转发到我们的成功页面中
req.getRequestDispatcher("/s1").forward(req,resp);
}
Response即为从服务端产生的响应,主要用于产生对客户端的响应
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取文件路径
String realPath = "D:\\Environment\\WorkSpaceIdea\\JavaWebStudy\\HttpRequest\\target\\classes\\poster.png";
//获取文件名
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
//设置下载服务
resp.setHeader("Content-Disposition","attachment;filename="+fileName);
//获取文件输入流
FileInputStream in =new FileInputStream(realPath);
//创建缓冲区
int len=0;
byte[] buffer =new byte[1024];
//获取OutputStream对象
ServletOutputStream out = resp.getOutputStream();
//进行输出到客户端
while((len=in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
out.close();
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置响应头,让浏览器每5秒刷新一次
resp.setHeader("refresh","5");
//在内存中创建一张图片
BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
//得到图片
Graphics2D g = (Graphics2D) image.getGraphics();
//绘制图片
g.setColor(Color.BLACK);
g.fillRect(0,0,80,10);
g.setColor(Color.WHITE);
g.setFont(new Font(null,Font.BOLD,20));
g.drawString(makeNum(),0,20);
//告诉浏览器我们想要响应一个图片
resp.setContentType("image/jpeg");
//不让浏览器进行缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("pragma","no-cache");
//把图片写给浏览器
ImageIO.write(image,"jpg", resp.getOutputStream());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
//生成随机数
private String makeNum(){
Random random =new Random();
String num =String.valueOf(random.nextInt(99999999));
StringBuffer sb =new StringBuffer();
for(int i=0;i<8-num.length();i++){
sb.append("0");
}
return sb.toString()+num;
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.sendRedirect("/down");//将请求重定向到/down请求下
}
Cookie,有时也用其复数形式 Cookies。类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息
客户端保存技术
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决中文乱码问题
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//从请求中获取Cookie
Cookie[] cookies = req.getCookies();
//处理cookies
if(cookies!=null){
for (Cookie cookie : cookies) {
if(cookie.getName().equals("LastLoginTime")){
String value = cookie.getValue();
long l = Long.parseLong(value);
Date date = new Date(l);
resp.getWriter().write("你上一次登录本站的时间为:"+date.toString());
}
}
}
Cookie lastLoginTime = new Cookie("LastLoginTime", System.currentTimeMillis() + "");
//通过resp响应一个cookie给客户端
lastLoginTime.setMaxAge(24*60*60);//设置cookie有效期为1天,以秒为单位
resp.addCookie(lastLoginTime);
}
在计算机中,尤其是在网络应用中,称为“会话控制”。Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web页时,如果该用户还没有会话,则Web服务器将自动创建一个 Session对象。当会话过期或被放弃后,服务器将终止该会话。
sessionID可以用作用户的标识
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
//得到session
//HttpSession
req.getSession().setAttribute("name","haha");
//获得SessionID
String sessionId=req.getSession().getId();
//测试Session的创建情况
if(req.getSession().isNew()){
resp.getWriter().write("New session,ID"+sessionId);
}else{
resp.getWriter().write("Old session ID"+sessionId);
resp.getWriter().write((String) req.getSession().getAttribute("name"));
//Old session ID06F5EBBF8AD139F723F9E0C941AA9C65haha
}
}
我们可以在Xml中设置session的失效时间
<session-config>
<session-timeout>15session-timeout>
session-config>
应用:
我们通常会选择将一些在一个网站各个页面通用的数据放在Session中,进行会话级别的数据保存
Servlet 过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息。
可以将一个或多个 Servlet 过滤器附加到一个 Servlet 或一组 Servlet。Servlet 过滤器也可以附加到 JavaServer Pages (JSP) 文件和 HTML 页面。调用 Servlet 前调用所有附加的 Servlet 过滤器。
应用:中文乱码过滤器
public class Myfilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//利用Filter进行乱码过滤
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
chain.doFilter(request,response);//把请求和响应发出,不发出页面就会卡住
}
@Override
public void destroy() {
}
}
<filter>
<filter-name>codefilter-name>
<filter-class>Myfilterfilter-class>
filter>
<filter-mapping>
<filter-name>codefilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
事件(Event)是发生的事情,在Web应用程序世界中,事件可以是应用程序的初始化,销毁应用程序,从客户端请求,创建/销毁会话,会话中的属性修改等。
Servlet API提供了不同类型的侦听器接口,我们可以在web.xml中实现和配置,以便在特定事件发生时处理某些事件
使用方法:
public class MyListener implements HttpSessionListener {
//创建session监听,监听session的创建
@Override
public void sessionCreated(HttpSessionEvent se) {
ServletContext servletContext = se.getSession().getServletContext();
Integer sessionCut = (Integer) servletContext.getAttribute("SessionCut");
if(sessionCut == null){
sessionCut=new Integer(1);
}else{
int value =sessionCut.intValue();//拆箱
sessionCut=new Integer(value+1);//装箱
}
servletContext.setAttribute("SessionCut",sessionCut);
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
}
}
<listener>
<listener-class>MyListenerlistener-class>
listener>
Login
<%=this.getServletConfig().getServletContext().getAttribute("SessionCut")%>
在前端页面中获取(这里开了两个浏览器模拟两个session)