一天学会sevlert基础
创建servlet步骤:
在pom.xml文件里面导入依赖:
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
scope表示这个依赖【jar包】生效的范围,默认是编译环境也就是complie,如果是test表示只有在测试目录下有效,provided表示在编译环境和测试环境都可以使用这个jar包,运行的时候不会使用这个jar包
java文件夹下面创建java文件,继承servlet类,并且实现servlet的方法:
loadOnStartup默认是-1,代表该内容是第一次访问,如果改成1,表示不是第一次访问了,此时不会调用init方法
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet(urlPatterns="/demo2",loadOnStartup = 1)
public class ServletDemo1 implements Servlet {
public void init(ServletConfig servletConfig) throws ServletException {
}
public ServletConfig getServletConfig() {
return null;
}
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("servlet hello world");
}
public String getServletInfo() {
return null;
}
public void destroy() {
}
}
service(ServletRequest servletRequest, ServletResponse servletResponse)方法里面的方法体是需要写的,这里我写了个输出语句,然后启动tomcat,就可以运行你的java代码了
servlet执行流程$生命周期
执行流程:web项目->tomcat创建servlet对象并且调用里面的service方法
- 加载和实例化:当servlet第一次被访问的时候,由容器创建servlet对象
- 初始化:完成初始化,默认servlet第一次被访问的时候调用,且只调用一次:init()
- 请求处理:每次servlet被访问【刷新】,该方法都会被加载
- 服务终止:在servlet被销毁的时候【内存释放/服务器关闭】会被调用destroy方法
servlet接口中的方法介绍:
init(ServletConfig servletConfig):初始化
service(ServletRequest servletRequest, ServletResponse servletResponse):提供服务方法
destroy():销毁
ServletConfig getServletConfig():获取servletconfig对象
String getServletInfo():获取servlet信息
下面的方式使用HttpServlet
@WebServlet(urlPatterns = "/demo3")
public class ServletDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
相当于:
- 创建一个继承servlet的类,在该类中判断请求方式
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
HttpServletRequest request= (HttpServletRequest) servletRequest;
//得到请求方式
String method = request.getMethod();
if("GET".equals(method)){
doGet();
}else if("POST".equals(method)){
doPost();
}
}
//希望子类可以重写,因此我们用protected
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
}
- 子类继承的时候可以对方法进行重写
@WebServlet(urlPatterns = "/demo3")
public class ServletDemo3 extends ServletDemo4 {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
servlet urlPatterns 配置
- 利用注解的方式:
@WebServlet(urlPatterns = "/demo3",“/demo4”):表示访问这个servlet的时候可以用这几个路径
- 不用注解,在web.xml文件中配置该servlet【较老的方法】
<!--获取需要访问的servlet类-->
<servlet>
<servlet-name>demo3</servlet-name>
<servlet-class>com.liku.web.ServletDemo3</servlet-class>
</servlet>
<!--配置访问路径-->
<servlet-mapping>
<servlet-name>demo3</servlet-name>
<url-pattern>/demo3</url-pattern>
</servlet-mapping>
request:
请求行
String getMethod():获取请求方式
String getContextPath():获取虚拟目录
StringBuffer getRequestURL():获取统一资源定位符
String getRequestURI():获取统一资源标识符
String getQueryString():获取请求参数(GET方式才有)
写一个页面,提交地址写我们servlet的web地址
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>部署的第一个网页</title>
</head>
<body>
<form action="/rqd1" method="get">
<input type="text" name="username"/>
<br/>
<input type="text" name="pwd"/><input type="submit"/>
</form>
</body>
</html>
@WebServlet("/rqd1")
public class RequestDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求方式:GET
String method = req.getMethod();
System.out.println(method);
//获取虚拟目录
String contextPath = req.getContextPath();
System.out.println(contextPath);
//获取URL:http://localhost:8088/rqd1
StringBuffer requestURL = req.getRequestURL();
System.out.println(requestURL);
//获取URI:/rqd1
String requestURI = req.getRequestURI();
System.out.println(requestURI);
//获取请求参数:username=sad&pwd=asf
String queryString = req.getQueryString();
System.out.println(queryString);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
请求头
String getHeader(String name)
请求体
ServletInputStream getInputStream():获取字节输入流
BufferReader getReader():获取字符输入流【POST方式】
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
BufferedReader reader = req.getReader();
String s = reader.readLine();
System.out.println(s);
}
request通用方式获取请求参数:
Map<String,String[]> getParameterMap():获取所有参数组成的map集合
String[] getParameterValues(String name):根据名称获取参数值【数组】
String getParameters(String name)根据名称获取参数值【单个值】
我把页面的请求方式改为get,在get中调用上面的几个方法:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("hello,servlet-get");
Map<String, String[]> parameterMap = req.getParameterMap();
Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();
for (Map.Entry<String, String[]> entry : entries) {
System.out.println(entry.getKey()+": "+Arrays.toString(entry.getValue()));
}
Enumeration<String> parameterNames = req.getParameterNames();
String str;
while ((str=parameterNames.nextElement())!=null){
System.out.println(str);
}
String pwd = req.getParameter("pwd");
System.out.println(pwd);
}
当我把请求方式修改成post,并且在post中调用该方法,发现也是可以的,因此这种方式是通用的请求参数方式
请求参数有中文会出现乱码:
因为tomcat底层的编码格式时URL编码,但是使用的ISO-8859-1解码,因此会出现乱码,乱码处理方式如下:
对于post请求方式,因为post获取参数调用的时writer的方法,把编码格式改一下就可以:直接利用方法来修改编码格式,我这里页面时utf-8,因此servlet也是utf-8
request.setCharacterEncoding("UTF-8");
对于get请求方式:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
username=new String(username.getBytes(StandardCharsets.ISO-8859-1),StandardCharsets.UTF_8);
//我这里页面编码格式为utf-8,所以这种方式是没用的
System.out.println(username);
}
在tomcat8后,如果网页的编码方式是UTF-8,使用GET方法提交请求是不用处理乱码问题的,因为tomcat8后默认编码处理方式是UTF-8,编码形式不冲突,就不会有乱码问题. 如果网页的编码方式不是"utf-8",则可以采取以上两种方式解决乱码问题.
请求转发forword
一种在服务器内部的资源跳转方式:
代码如下【我这里页面的请求方式是get】:
请求转发资源间的共享数据常用的方法:
void setAttribute(String name,Object obj)
Object getAttribute(String name)
void removeAttribute(String name)
@WebServlet("/rqs2")
public class RequestDemo2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo2.get");
request.setAttribute("username","hello");
request.getRequestDispatcher("/RequestDemo3").forward(request,response);<br/>
}
}
@WebServlet("/RequestDemo3")<br/>
public class RequestDemo3 extends HttpServlet {<br/>
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println(request.getAttribute("username"));
}
}
请求转发的特点:
-
请求转发浏览器地址栏路径不会发生变化
-
只能转发到当前服务器的内部资源
-
只有一次请求,可以在转的资源间使用request共享数据
Response:
响应数据分为三部分:
- 响应行
void setStatus(int sc):设置响应状态码
- 响应头
void setHeader(String name,String value):设置响应头键值对
- 响应体
PrintWriter getWriter():获取字符输出流
ServletOutputStream getOutputStream():获取字节输出流
redirect完成重定向:
也是一种资源跳转方式,但是跟请求转发不一样:
资源A实现重定向方式:
-
resp.setStatus(302); resp.setHeader("location","资源B的路径")
-
response.sendRedirect("资源B的路径");
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo2.get");
response.setStatus(302);
response.setHeader("location", "/RequestDemo3");
//这里路径,如果是新版的不需要加项目名称
response.sendRedirect("/RequestDemo3");
}
重定向的特点:
- 浏览器的地址栏会发生变化
- 重定向可以到任意位置的资源
- 两次请求,不能在多个资源使用request共享数据
路径问题:
- 浏览器使用:需要加虚拟目录
- 服务器使用:不需要加虚拟目录
response响应字符数据
PrintWriter a=response.getWriter()
a.writer("aaa"); //向页面上写内容
如果想在页面上写一些标签,需要设置内容类型
如果是中文需要看一下你页面的编码格式,然后解码格式也要设置成相应的格式,我这里中文解码格式是GBK,因此我把编码格式也改成GBK就不会出现乱码
response.setCharacterEncoding("GBK");
response.setHeader("content-type", "text/html");
也可以直接:
response.setContentType("text-html;charset=xx");
Response响应字节数据
ServletOutputStream stream=resp.getOutputStream();
stream.write(字节数据);
从本地上传一张图片:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletOutputStream outputStream = response.getOutputStream();
InputStream inputStream=new FileInputStream("E:\\欧阳路路\\student\\07欧阳路路\\HbuilderX\\day01\\img/R-C.jpg");
byte[] bytes=new byte[1024];
int len;
while ((len=inputStream.read(bytes))!=-1){
outputStream.write(bytes,0,len);
}
}
但是上面的方法是初学io的时候用的方法,我们现在可以直接用工具包,在pom.xml导入依赖:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
使用的时候导包别导错了,是下面的包:
import org.apache.commons.io.IOUtils;
上面上传我们就简化成:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletOutputStream outputStream = response.getOutputStream();
InputStream inputStream=new FileInputStream("E:\\欧阳路路\\student\\07欧阳路路\\HbuilderX\\day01\\img/R-C.jpg");
IOUtils.copy(inputStream,outputStream);
}