常见问题:
JavaWeb工程中编写servelet程序。
刚开始的时候没有导入相应的jar包,所以不会自动导入Servlet包。
添加相应的jar包。
File->>project Structureàlibraries
选择加号,点击Java
找到Tomcat安装目录下的lib文件,
添加Servlet-api.jar
点击ok
然后选择相应的模块
点击OK
最后点击apply即可
1.什么是SerVlet?
Servlet是JAVAEE规范之一。规范就是接口
Servelet就是JavaWeb三大组件之一,三大组件分别是:Servlet程序,Filter过滤器,Listener监听器
Servlet是运行在服务器上的一个Java小程序,它可以接收客户端发送过来的请求,并相应数据给客户端。
2.手动实现Servlet程序
编写一个类去实现Servlet接口
实现service方法,处理请求,并响应数据
到web.xml中去配置Servlet程序的访问地址
例如下面的HelloServlet程序
package com.lsy.servlet1;
import javax.servlet.*;
import java.io.IOException;
/**
* @Description:
* @Author:lsy
* @Date:
*/
public class HelloServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* service方法是专门处理请求和响应的,也就是说,当浏览器访问到HelloServlet时,就会执行这个方法。
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("hello servlet 被访问了");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
web.xml 程序
<?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标签 Servlet程序起一个别名(一般是类名) -->
<servlet-name>HelloServlet</servlet-name>
<!--servlet-class是Servlet程序的全类名-->
<servlet-class>com.lsy.servlet1.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<!--servlet-name标签的作用是告诉服务器,我当前配置的地址给哪个Servlet程序使用-->
<servlet-name>HelloServlet</servlet-name>
<!--
url-pattern标签配置访问地址 <br/>
/ 斜杠在服务器解析的时候,表示地址为:http://ip:port/工程路径 <br/>
/hello 表示地址为:http://ip:port/工程路径/hello <br/>
相当于http://ip:port/JavaWeb/hello
就是当前的JavaWeb部署到了Tomcat服务器,http://ip:port/JavaWeb/hello就是部署的工程下的具体的路径
http://ip:port/JavaWeb/hello访问这个就是相当于执行了helloServlet类中service()方法
在IDEA中的控制台就会输出helloServlet中的输出语句
如果将/hello换成/abc 那么在访问helloServlet时的访问地址是 http://ip:port/JavaWeb/abc
-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
执行时一些常见的错误;
常见错误一:url-pattern中配置的路径没有以斜杠开头
常见错误二:servlet-pattern中配置的值不存在:
常见错误三:
Servlet-class标签的全类名配置错误:
3.URL地址到Serve两同程序访问的过程
4.Servlet的声明周期
package com.lsy.servlet1;
import javax.servlet.*;
import java.io.IOException;
/**
* @Description:
* @Author:lsy
* @Date:
*/
public class HelloServlet implements Servlet {
/**
* 初始化方法
* @param servletConfig
* @throws ServletException
*/
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* service方法是专门处理请求和响应的,也就是说,当浏览器访问到HelloServlet时,就会执行这个方法。
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("hello servlet 被访问了");
}
@Override
public String getServletInfo() {
return null;
}
/**
* 销毁方法,只有在web工程停止的时候使用
*/
@Override
public void destroy() {
}
}
5.Get和Post请求的分发处理。
在处理请求和相应的时候,我们通过传入的参数,处理相应的get和post请求。
ServletRequest 的子类有getMethod方法。getMethod方法获得的是字符串:“POST”,“GET”
在service程序中进行如下处理:
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
/*
在处理请求和相应的时候,我们通过传入的参数,处理相应的get和post请求。
ServletRequest 的子类有getMethod方法。
*/
System.out.println("hello servlet 被访问了");
//向下转型。
HttpServletRequest httpServletRequest=(HttpServletRequest) servletRequest;
String method=httpServletRequest.getMethod();//GET POST
if("GET".equals(method)){
doGet();
}else if("POST".equals(method)){
doPost();
}
}
private void doPost() {
System.out.println("处理post请求的操作");
}
private void doGet() {
System.out.println("处理Get请求的操作");
}
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://localhost:8080/06_servlet/hello3" method="post">
<input type="hidden" name="action" value="login" />
<input type="hidden" name="username" value="root" />
<input type="submit">
</form>
</body>
</html>
当我们访问http://localhost:8080/javaWeb/a.html时,点击按钮,就会自动的跳到http://localhost:8080/javaWeb/hello页面执行service方法,执行相应的GET和POST方法。
6.通常通过继承HTTPServlet实现Servlet程序
上面是通过实现Servlet接口编写的Servlet程序,
在HttpServlet类中有doGet()和DoPost()方法,根据业务需求进行重写
package com.lsy.servlet1;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @Description:
* @Author:lsy
* @Date:
*/
public class HelloServlet2 extends HttpServlet {
/**
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServlet2 的doGet方法");
}
/**
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServlet2 的doPost方法");
}
}
web.xml
<servlet>
<servlet-name>HelloServlet2</servlet-name>
<servlet-class>com.lsy.servlet1.HelloServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet2</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
程序会自动的根据请求方式进行响应。自动执行相应的doGET和doPOST方法。
7.使用IDEA类自动生成Servlet程序
选择 File->project structure->facets
将Source RootS中有Src的勾选上就行了
然后右键包名,选择Servlet
填写相应的信息,取消下面的对钩
自动生成的Servlet程序
在Web.xml中会自动生成
手动配上相应的地址就行
8.Servlet类的继承体系
9.ServletConfig类:
- ServletConfig类从类名上来看,就知道是Servlet程序的配置信息类。
- Servlet程序和ServletConfig对象都是有Tomcat负责创建,我们只是负责使用。
- Servlet程序默认是第一次访问的时候创建,ServletConfig是每一个Servlet程序创建时,就创建一个对应的ServletConfig对象。
ServletConfig类的三大作用:
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2 init初始化方法");
// 1、可以获取Servlet程序的别名servlet-name的值
System.out.println("HelloServlet程序的别名是:" + servletConfig.getServletName());
// 2、获取初始化参数init-param
System.out.println("初始化参数username的值是;" + servletConfig.getInitParameter("username"));
System.out.println("初始化参数url的值是;" + servletConfig.getInitParameter("url"));
// 3、获取ServletContext对象
System.out.println(servletConfig.getServletContext());
}
web.xml中的配置:
<!-- servlet标签给Tomcat配置Servlet程序 -->
<servlet>
<!--servlet-name标签 Servlet程序起一个别名(一般是类名) -->
<servlet-name>HelloServlet</servlet-name>
<!--servlet-class是Servlet程序的全类名-->
<servlet-class>com.lsy.servlet1.HelloServlet</servlet-class>
<!--init-param是初始化参数-->
<init-param>
<!--是参数名-->
<param-name>username</param-name>
<!--是参数值-->
<param-value>root</param-value>
</init-param>
<!--init-param是初始化参数-->
<init-param>
<!--是参数名-->
<param-name>url</param-name>
<!--是参数值-->
<param-value>jdbc:mysql://localhost:3306/test</param-value>
</init-param>
</servlet>
注意点:
在doGethe DoPost方法中可以获取到相应的ServletConfig,但是这个ServletConfig获得的参数信息是当前Servlet程序的,也就是说,每一个Servlet程序对应一个ServletConfig。
(在Servlethello2中不能通过ServletConfig开获取ServletHello中所配置的参数信息)
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletConfig servletConfig=getServletConfig();
System.out.println("HelloServlet2 的doGet方法");
//在HelloServlet2的配置信息中配置相应的信息,如果在HelloServlet2中没有相应的信息,就会出错
// 1、可以获取Servlet程序的别名servlet-name的值
System.out.println("HelloServlet程序的别名是:" + servletConfig.getServletName());
// 2、获取初始化参数init-param
System.out.println("初始化参数username的值是;" + servletConfig.getInitParameter("username"));
System.out.println("初始化参数url的值是;" + servletConfig.getInitParameter("url"));
// 3、获取ServletContext对象
System.out.println(servletConfig.getServletContext());
}
//如果重写了init方法,在里面做了一些初始化工作,就必须调用 super.init(config);
//否则会出现空指针异常
因为在子类中重写init方法的话,程序执行的时候就会执行的是子类的方法,在父类GenericServlet中有一个保存config的工作,如果不调用父类的init方法,这个保存操作就会丢失
GenericServlet中的init方法:
package com.lsy.servlet1;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @Description:
* @Author:lsy
* @Date:
*/
public class HelloServlet2 extends HttpServlet {
//如果重写了init方法,在里面做了一些初始化工作,就必须调用 super.init(config);
//否则会出现空指针异常
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
System.out.println("初始化工作");
}
/**
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletConfig servletConfig=getServletConfig();
System.out.println("HelloServlet2 的doGet方法");
// 1、可以获取Servlet程序的别名servlet-name的值
System.out.println("HelloServlet程序的别名是:" + servletConfig.getServletName());
// 2、获取初始化参数init-param
System.out.println("初始化参数username的值是;" + servletConfig.getInitParameter("username"));
System.out.println("初始化参数url的值是;" + servletConfig.getInitParameter("url"));
// 3、获取ServletContext对象
System.out.println(servletConfig.getServletContext());
}
/**
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServlet2 的doPost方法");
}
}
10、ServletContext类
什么是ServletContext?
ServletContext类的四个作用
- 获取web.xml中配置的上下文参数context-param
- 获取当前的工程路径,格式:/工程路径
- 获取工程部署后在服务器硬盘上的绝对路径
- 想Map一样存取数据
web.xml文件
<!--context-param表示的是上下文参数(它属于整个工程)-->
<context-param>
<param-name>username</param-name>
<param-value>lsy</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>lsy123</param-value>
</context-param>
<servlet>
<servlet-name>ServletContext1</servlet-name>
<servlet-class>com.lsy.servlet1.ServletContext1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletContext1</servlet-name>
<url-pattern>/context1 </url-pattern>
</servlet-mapping>
package com.lsy.servlet1; /**
* @Description:
* @Author:lsy
* @Date:
*/
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class ServletContext1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// ServletContext servletContext = getServletConfig().getServletContext();
//也可以直接使用getServletContext()
//因为在getServletConfig()中也就是直接调用的getServletContext()
//1.获取Web.xml中配置的上下文参数
ServletContext servletContext = getServletContext();
String username = servletContext.getInitParameter("username");
String password = servletContext.getInitParameter("password");
System.out.println(username);
System.out.println(password);
//2.获取当前的工程路径名
String contextPath = servletContext.getContextPath();
System.out.println(contextPath);///javaWeb
//3.获取工程部署后在服务器硬盘上的绝对路径
//"/"被服务器解析地址为:http://ip:port/工程名/ 映射到idea代码的web目录下
String realPath = servletContext.getRealPath("/");
System.out.println(realPath);//E:\IdeaProjects\JavaWeb\out\artifacts\javaWeb_war_exploded\
//4.和Map一样存储数据
System.out.println("保存之前,key1的值:"+servletContext.getAttribute("key1"));//null
servletContext.setAttribute("key1","value1");
System.out.println("保存之后,key1的值:"+servletContext.getAttribute("key1"));//value1
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
11.HTTP协议
什么是HTTP协议:
Http协议中的数据右叫报文。
12.请求的HTTP协议
请求有POST和GET两种
GET请求:
①请求行
- 请求的方式 GET
- 请求的资源路径[+?+请求参数]
- 请求的协议版本号 HTTP/1.1
②请求头
key:value 组成 不同的键值对,表示不同的含义。
POST请求
①请求行
- 请求的方式 GET
- 请求的资源路径[+?+请求参数]
- 请求的协议版本号 HTTP/1.1
②请求头
key:value 组成 不同的键值对,表示不同的含义。
空行
③请求体 就是发送给服务器的数据
哪些是GET请求哪些是POST请求?
13.相应的HTTP协议格式:
①响应行
- 响应的协议和版本号
- 响应的状态码
- 响应状态描述符
②响应头
key:value 组成 不同的响应头,表示不同的含义。
空行
③响应体 就是回传给客户端数据
一般相应体会单独的放在respond中
14.常用的响应码说明
200:表示请求响应成功
302:表示请求重定向
404:表示请求服务器已经收到了,但是你要的数据不存在
500:表示请求服务器已经收到了,但是服务器内部错误(代码错误)
15、MIME类型的说明