Servlet学习
Servlet是基于Java语言的Web服务器编程技术,是Sun公司提出的一种实现动态网页的解决方案。Servlet程序是一个运行在服务器中的特殊Java类,它能够处理来自客户端的请求并生成相应。其实servlet就是继承了HttpServlet、复写了service的Java类。一、使用1、创建普通的Java类并继承HttpServlet2、复写service方法3、在se...
Servlet是基于Java语言的Web服务器编程技术,是Sun公司提出的一种实现动态网页的解决方案。Servlet程序是一个运行在服务器中的特殊Java类,它能够处理来自客户端的请求并生成相应。其实servlet就是继承了HttpServlet、复写了service的Java类。
一、使用
1、创建普通的Java类并继承HttpServlet
2、复写service方法
3、在service方法中书写逻辑代码
4、在webContent下的WEB-INF文件夹下的web.xml文件中配置servlet
二、把tomcat集成到eclipse
Window -> Preferences-->Server-->Runtime Enviroments,点击右侧的Add
选择自己下载的tomcat的版本,Next
选择自己tomcat的路径,finish就好了。
三、第一个servlet
Java类:
package com.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().write("it is my first servlet");
System.out.println("it is my first servlet.");
}
}
Web.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<!-- 配置Servlet -->
<!-- 配置servlet类路径 -->
<servlet>
<servlet-name>my</servlet-name>
<servlet-class>com.servlet.MyServlet</servlet-class>
</servlet>
<!-- 配置访问方式 -->
<servlet-mapping>
<servlet-name>my</servlet-name>
<url-pattern>/my</url-pattern>
</servlet-mapping>
</web-app>
url的组成:
http://localhost:8080/MyServlet/my
服务器地址:端口号/类名/servlet别名
报错:
404:没找到这个类
500:找到了没这个类
四、servlet的生命周期
1、从第一次调用到服务器关闭
2、如果Servlet在web.xml中配置了load-on-startup,生命周期为从服务器启动到服务器关闭
servlet:
package com.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Servletlife extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("servlet初始化完成");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("servlet life");
System.out.println("servlet life");
}
@Override
public void destroy() {
System.out.println("俺被销毁了");
}
}
web.xml:
<servlet>
<servlet-name>life</servlet-name>
<servlet-class>com.servlet.Servletlife</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>life</servlet-name>
<url-pattern>/life</url-pattern>
</servlet-mapping>
五、doGet方法和doPost方法
1、doGet:此方法被本类的service()调用,用来处理一个GET请求;
2、doPost:此方法被本类的service()调用,用来处理一个POST请求;
不管是get方式还是post方式,如果servlet类中有service方法,都会优先调用service方法。
3、Servlet常见错误:
404:资源未找到,未找到项目
500:内部服务器错误,未找到类
405:请求方式不支持,请求方式和servlet中的方法不匹配
六、request对象学习
1、作用
request对象中封存了当前请求的所有请求信息
2、使用
(1)获取请求行数据
getMethod() //获取请求方式
getRequestURL() //获取请求URL
getRequestURI() //获取URI
getScheme() //获取协议
(2)获取请求头数据
getHeader() //获取指定的请求头信息
getHeaderNames() //获取所有的请求行的键的枚举
(3)获取用户数据
getParameter() //获取用户数据
req.getParameterValues() 返回同键不同值的数据
注意:如果请求数据不存在,不会把错而是返回null
注意:request对象由tomcat服务器创建,并作为实参传递给处理请求的servlet的service方法
package com.servlet;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RequestServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求行数据
//获取请求方式
String method = req.getMethod();
System.out.println(method);
//获取请求URL
StringBuffer url = req.getRequestURL();
System.out.println(url);
//获取URI
String uri = req.getRequestURI();
System.out.println(uri);
//获取协议
String h = req.getScheme();
System.out.println(h);
//获取请求头数据
//获取指定的请求头信息
String value = req.getHeader("Accept");
System.out.println(value);
//获取所有的请求行的键的枚举
Enumeration e = req.getHeaderNames();
while(e.hasMoreElements()) {
String name = (String) e.nextElement();
String value2 = req.getHeader(name);
System.out.println(name+":"+value2);
}
//获取用户数据
String name = req.getParameter("uname");
String pwd = req.getParameter("pwd");
System.out.println(name+":"+pwd);
//返回同键不同值的数据
String[] favs = req.getParameterValues("fav");
if(favs!=null) {
for(String fav:favs) {
System.out.println(fav);
}
}
}
}
使用的一个jsp来写了一个表单:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<form action="request" method="get">
用户名:<input type="text" name="uname" value=""></br>
密码:<input type="test" name="pwd" value=""></br>
爱好: </br>
<input type="checkbox" name="fav" value="1">唱</br>
<input type="checkbox" name="fav" value="2">跳</br>
<input type="checkbox" name="fav" value="3">rap</br>
<input type="submit" value="登录">
</form>
</body>
</html>
结果:
七、Response对象
响应处理结果
1、设置响应头
resp.setHeader(String name,String value); //在响应头添加响应信息,但同键会覆盖
resp.addHeader(String name,String value); //在响应头添加响应信息,同键不会覆盖
2、设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
3、设置值响应状态码
resp.sendError(int num,String msg); //自定义响应状态码
4、设置响应实体
resp.getWriter().write(String str); //响应具体的数据给浏览器
5、service请求处理响应代码流程:
设置响应编码格式
获取请求数据
处理请求数据
响应处理结果
代码:
package com.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ResponseServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//相应处理结果
//设置响应头
resp.setHeader("fruit", "banana");
resp.addHeader("food", "hotpot");
//设置响应编码格式
//resp.setContentType("text/plain;charset=utf-8");
//resp.setContentType("text/xml;charset=utf-8");
resp.setContentType("text/html;charset=utf-8");
//设置值响应状态码
//resp.sendError(404, "sorry");
//设置响应实体
resp.getWriter().write("<b>今天天气真好,但是我出不去</b>");
}
}
效果:
6、Servlet流程总结:
浏览器发起请求到服务器(请求)
服务器接收浏览器的请求,进行解析,创建request对象存储请求数据
服务器调用对应的servlet进行请求处理,并将request对象作为实参传递给servlet的方法
servlet的方法执行进行请求处理
设置请求编码格式
设置响应编码格式
获取请求信息
处理请求信息
创建业务层对象
调用业务层对象的方法
响应处理结果
7、请求转发学习:
作用:实现多个servlet联动操作处理请求,这样避免代码冗余,让servlet的职责更加明确
req.getRequestDispatcher(要转发的地址).forword(req,resp);
特点:一次请求,浏览器地址不变
注意:请求转发后直接return结束即可
8、request作用域
一次请求中的所有servlet
作用:解决了一次请求内不同servlet的数据(请求数据+其他数据)共享问题
数据流转:
request.setAttribute(Object name,Object value);
request.getAttribute(Object obj)
9、重定向
解决了表单重复提交的问题,以及当前servlet无法处理的请求的问题
使用:resp.sendRedirect(String uri)
例:resp.sendRedirect("/login/main"); //login后重定向到main
特点:
两次请求,两个request对象
浏览器地址栏改变
使用时机:
如果请求中有表单数据,而数据有比较重要,不能重复提交,建议使用重定向
如果请求被servlet接收后,无法进行处理,建议使用重定向定位到可以处理的资源
八、Cookie技术
1、作用:
解决了发送的不同请求的数据共享问题
2、使用:
(1)Cookie的创建和存储
创建Cookie对象
Cookie c = new Cookie(String name,String value);
设置Cookie
设置有效期:c.setMaxAge(int seconds); //Cookie的有效期
设置有效路径:c.setPath(String uri); //该路径下携带Cookie
响应Cookie信息给客户端
resp.addCookie(c)
(2)Cookie的获取
获取Cookie信息数组
Cookie[] cks = req.getCookies();
遍历数组获取Cookie信息,使用for循环即可
if(cks!=null){
for(Cookie c:cks){
String name = c.getName();
String value = c.getValue();
System.out.println(name+":"+value);
}
}
注意:
一个Cookie对象存储一条数据。多条数据,可以多建几个Cookie对象存储
package com.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CookieServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
//处理请求信息
//相应处理结果
//使用Cookie进行浏览器端的数据存储
//创建Cookie对象
Cookie c = new Cookie("food","hotpot");
Cookie c2 = new Cookie("fruit","banana");
//设置Cookie
//设置Cookie有效期(三天)
c2.setMaxAge(3*24*3600);
//响应Cookie信息
resp.addCookie(c);
resp.addCookie(c2);
//直接响应
resp.getWriter().write("Cookie学习");
}
}
3、特点:
浏览器端的数据存储技术
存储的数据声明在服务器端
临时存储:存储在浏览器的运行内存中,浏览器关闭即失效
定时存储:设置了Cookie的有效期,存储在客户端的硬盘中,在有效期内符合路径要求的请求都会附带该信息
默认cookie信息存储好之后,每次请求都会附带,除非设置有效路径
九、session技术
1、原理:
用户第一次访问服务器,服务器会创建一个session对象给此用户,并将该session对象的JSESSIONID使用Cookie技术存储到浏览器中,保证用户的其他请求能够获取到同一个session对象,也保证了不同请求能够获取到共享的数据。
2、特点:
存储在服务器端
服务器进行创建
依赖Cookie技术
一次会话
默认存储时间是30分钟
3、作用:
解决了一个用户不同请求处理的数据共享问题
4、使用:
(1)创建session对象/获取session对象
HttpSession hs = req.getSession();
如果请求中拥有session的标识符也就是JSESSIONID,则返回其对应的session对象
如果请求中没有session的标识符也就是JSESSIONID,则创建新的session对象,并将其JSESSIONID作为从cookie数据存储到浏览器内存中
如果session对象是失效的,也会重新创建一个session对象,并将其JSESSIONID存储到浏览器内存中
(2)设置session存储时间
hs.setMaxInactiveInterval(int seconds);
注意:在指定的时间内session对象没有被使用则被销毁,如果使用了则重新计时
(3)设置session强制失效
hs.invalidate();
注意:
JSESSIONID存储在了cookie的临时存储空间中,浏览器关闭即失效
使用:
package com.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 javax.servlet.http.HttpSession;
public class SessionServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
String name = "张三";
//处理请求信息
//创建session对象
HttpSession hs = req.getSession();
//设置session存储时间(5s)
hs.setMaxInactiveInterval(5);
System.out.println(hs.getId());
//设置session强制失效
hs.invalidate();
//响应处理结果
resp.getWriter().write("session学习");
}
}
5、存储和获取数据:
存储:hs.setAttribute(String name,Object value);
获取:hs.getAttribute(String name);返回的数据类型为Object
注意:存储的动作和取出的动作发生在不同请求中,但是存储要先于取出
使用时机:
一般用户在登陆web项目时会将用户的个人信息存储到Session中,供该用户的其他请求使用
6、总结:
session解决了一个用户的不同请求的数据共享问题,只要在JSESSIONID不失效和session对象不失效的情况下。用户的任意请求在处理时都能获取到同一个session对象。
作用域:
一次会话
在JSESSIONID和SESSION对象不是小的情况下为整个项目内
session失效处理:
将用户请求中的JSESSIONID和后台获取到的SESSION对象的JSESSIONID精选比对,如果一致则session没有失效,如果不一致则证明session失效了。重定向到登陆页面,让用户重新登陆。
十、ServletContext
1、特点:
服务器创建
用户共享
2、作用域:
整个项目内
3、生命周期:
服务器启动到服务器关闭
4、使用:
(1)获取ServletContext对象
第一种方法
ServletContext sc = (ServletContext) this.getServletContext();
第二种方法
ServletContext sc2 = (ServletContext) this.getServletConfig().getServletContext();
第三种方法
ServletContext sc3 = (ServletContext) req.getSession().getServletContext();
(2)使用ServletContext对象完成数据共享
数据存储
sc.setAttribute("str","ServletContext对象学习");
数据获取
sc.getAttribute("str")
注意:不同的用户可以给ServletContext对象对象进行数据的存取
获取的数据不存在返回null
(3)获取项目中web.xml文件中的全局配置数据
sc.getInitParameter(String name);
根据键的名字返回web.xml中配置的全局数据的值,返回String类型。如果数据不存在返回null
sc.getInitParameterNames(); 返回键名的枚举
配置方式:
<context-param>
<param-name>name</param-name>
<param-value>zhangsan</param-value>
</context-param>
注意:一组<context-param>标签只能存储一组键值对数据,多组可以声明多个<context-param>进行存储
作用:将静态数据和代码进行解耦
(4)获取项目webroot下的资源的绝对路径
String path = sc.getRealPath(String path);
获取的路径为项目根目录,path参数为项目根目录中的路径
(5)获取webroot下的资源的流对象
InputStream is = sc.getResourceAsStream(String path);
注意:此种方式只能获取项目根目录下的资源流对象,class文件的流对象需要使用类加载器获取
小结:
request:一次请求中的数据共享
session:用户不同请求中的数据共享
ServletContext:不同用户的数据共享
十一、ServletConfig
获取在web.xml中给每个servlet单独配置的数据
使用:
获取Servlet Config对象
SercletConfig sc = this.getServletConfig();
获取web.xml中的配置数据
String code = sc.getInitParameter("config");
十二、web.xml:
Web项目下的web.xml文件为局部配置,针对本项目的位置。
Tomcat下的web.xml文件为全局变量,配置公共信息。
加载时机:服务器启动时。
热部署:
<Context path="/pet" reloadable="true" docBase="绝对路径" />
放到server.xml的<Host>下
路径下的文件必须存在,不存在的话就会报错
servlet重定向路径总结:
相对路径:从当前请求的路径查找资源的路径。
相对路径如果servlet的别名中包含目录,则会造成重定向资源查找失败。
绝对路径:第一个/表示服务器根目录
/虚拟项目名/资源路径
servlet请求转发:
/表示根目录
req.getRequestDispatcher("/资源路径").forward(req,resp);
更多推荐
所有评论(0)