5Servlet
Servlet
1简介
- Servlet就是sun公司开发动态web的一门技术
- Sun在这些API中提供一个接口叫做:Servlet
- 如果你想开发一个Servlet程序,只需要完成两个小步骤:1编写一个类,实现Servlet接口 2把开发好的Java类部署到web服务器中
- 我们把实现了Servlet接口的Java程序叫做Servlet
2编写一个servlet程序
- 导入依赖
- 实现Servlet 接口 直接继承 HttpServlet
- 编写Serviet 的映射(为什么写映射: 我们写的是JAVA程序,但是要通过浏览器访问,浏览器需要连接web浏览器, 所以我们需要在web服务中注册我们写的Servlet 还需要给他一个浏览器能够访问的路径)
<!-- 1pom.xml中导入依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
//2java.com.fao.servlet包下编写servlet类继承HttpServlet
public class helloservlet extends HttpServlet {
//由于gat或者post只是请求实现的不同方法,可以互相调用,业务逻辑一样
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//ervletOutputStream outputStream = resp.getOutputStream();
System.out.println("进入do get方法");
PrintWriter writer = resp.getWriter();//响应流
writer.print("hello servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<!-- 3.1配置映射方式一:xml方式,在web.xml下注册servlet -->
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 注册servlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.fao.servlet.helloservlet</servlet-class>
</servlet>
<!-- servlet请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
//3.2配置映射方式二:注解方式,在servler类上面加@WebServlet
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入doGet方法");
PrintWriter writer = resp.getWriter();
writer.write("hello servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
//乱码问题
public class ErrorServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决中文乱码
resp.setHeader("Content-type", "text/html;charset=UTF-8");
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
PrintWriter writer = resp.getWriter();
writer.print("<h1>404</h1>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3Servlet原理


4Mapping问题
- 一个Servlet可以指定一个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
- 一个Servlet可以指定多个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello3</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello4</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello5</url-pattern>
</servlet-mapping>
- 一个Servlet可以指定通用映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
- 默认请求路径
<!--默认请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
- 指定一些后缀或者前缀等等...
<!--可以自定义后缀实现请求映射
注意点,*前面不能加项目映射的路径
hello/sajdlkajda.fao
只要以 .fao 就能访问
-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.fao</url-pattern>
</servlet-mapping
- 优先级问题
- 指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求(404)
5ServletContext
- web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用
5.1共享数据
public class ServletContext1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//this.getServletConfig() //servlet 配置
//this.getInitParameter() //初始化参数
//this.getServletContext(); //servlet上下文
ServletContext context = this.getServletContext();
String username="Fao";//数据
context.setAttribute("username",username);//将一个数据保存在了ServletContext中, 名字为: username 值: username
System.out.println("欢迎");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
public class ServeletContext1a extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//数据
ServletContext context = this.getServletContext();
String username = (String)context.getAttribute("username");
////响应
resp.setContentType("text/html");
resp.setCharacterEncoding("UTF-8");
resp.getWriter().println("姓名: "+username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>servlet1</servlet-name>
<servlet-class>com.fao.servlet.ServletContext1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet1</servlet-name>
<url-pattern>/s1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>servlet1a</servlet-name>
<servlet-class>com.fao.servlet.ServeletContext1a</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet1a</servlet-name>
<url-pattern>/s1a</url-pattern>
</servlet-mapping>
5.2请求转发
public class ServletContext2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
System.out.println("进入到servletcontext2");
RequestDispatcher requestDispatcher = context.getRequestDispatcher("/hello");//转发的请求路径
requestDispatcher.forward(req,resp);//调用forward实现请求转发
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
<servlet>
<servlet-name>servlet2</servlet-name>
<servlet-class>com.fao.servlet.ServletContext2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet2</servlet-name>
<url-pattern>/s2</url-pattern>
</servlet-mapping>
5.3读取资源文件
- 在java目录下新建properties,在resources目录下新建properties
- 发现: 都被打包到了同一路径下: classes,俗称为类路径
- 如果测试报未找到文件,很有可能是maven没加过滤
//ServletContext3.properties
username=fao
id=1
password=123
public class ServletContext3 extends HelloServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
InputStream is = context.getResourceAsStream("/WEB-INF/classes/com/fao/servlet/ServletContext3.properties");
Properties prop = new Properties();
prop.load(is);
String username = prop.getProperty("username");
String id = prop.getProperty("id");
String passworld = prop.getProperty("password");
resp.getWriter().println(username+", "+passworld+", "+id);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>servlet3</servlet-name>
<servlet-class>com.fao.servlet.ServletContext3</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet3</servlet-name>
<url-pattern>/s3</url-pattern>
</servlet-mapping>
6HttpServletResponse&
- web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse
- 如果要获取客户端请求过来的参数:找HttpServletRequest
- 如果要给客户端响应一些信息:找HttpServletResponse
6.1简单分类
//负责向浏览器发送数据的方法
ServletOutputStream getOutputStream()throwsIOException;
PrintWriter getWriter()throwsIOException;//一般中文用
//负责向浏览器发送响应头的方法
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setDateHeader(String var1,long var2);
void addDateHeader(String var1,long var2);
void setHeader(String var1,String var2);
void addHeader(String var1,String var2);
void setIntHeader(String var1,int var2);
void addIntHeader(String var1,int var2);
6.2常见应用之下载文件
- 要获取下载文件的路径
- 下载的文件名是啥?
- 设置想办法让浏览器能够支持下载我们需要的东西
- 获取下载文件的输入流
- 创建缓冲区
- 获取OutputStream对象
- 将FileOutputStream流写入到buffer缓冲区
- 使用OutputStream将缓冲区中的数据输出到客户端!
//先在resources下放一张图片
public class ServletResponse4 extends HelloServlet {
@Override
protected void doGet(HttpServletRequest req, javax.servlet.http.HttpServletResponse resp) throws ServletException, IOException {
//1要获取下载文件的路径
String realPath = "D:\\java\\faoservletfuxi\\servletfuxi1\\src\\main\\resources\\4.jpg";
System.out.println(realPath);
//2下载的文件名是啥
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);//等于4.jpg
//3设置想办法让浏览器能够支持下载我们需要的东西
//如果是中文文件名需要设置编码 否则有可能乱码
resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));
//4获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
//5创建缓冲区
int len=0;
byte[] buffer = new byte[1024];
//6获取outputstream对象
ServletOutputStream out = resp.getOutputStream();
//7将outputstram流写入到buffer缓冲区
while ((len=in.read(buffer))!=-1){
out.write(buffer,0,len);
}
//8流关闭
in.close();
out.close();
}
@Override
protected void doPost(HttpServletRequest req, javax.servlet.http.HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>servlet4</servlet-name>
<servlet-class>com.fao.servlet.ServletResponse4</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet4</servlet-name>
<url-pattern>/s4</url-pattern>
</servlet-mapping>
6.3常见应用之实现重定向
- B一个web资源收到客户端A请求后,B会通知A去访问另外一个web资源C,这个过程叫重定向
- 重定向和转发的区别?
- 相同点:页面都会跳转
- 不同点:1请求转发 url不会产生变化, 重定向会发生变化 2请求转发 可以携带参数, 重定向不能携带参数 3请求转发 只能发送一个请求, 重定向至少发送两次请求
<%-- 成功页面 --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>
success
</h1>
</body>
</html>
public class ServletResponse5 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入请求");
//处理请求
//从那个请求中获取参数
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username+" : "+password);
//重定向时一定要注意路径问题 否则44
resp.sendRedirect("/fx1/success.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>servlet5</servlet-name>
<servlet-class>com.fao.servlet.ServletResponse5</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet5</servlet-name>
<url-pattern>/s5</url-pattern>
</servlet-mapping>
6.4HttpServletRequest之获取前端传递的参数 并 请求转发
- HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息
<%-- login.jsp --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<div style="text-align: center">
<%-- {pageContext.request.contextPath}表示当前页面 --%>
<form action="${pageContext.request.contextPath}/s6" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
爱好:
<input type="checkbox" name="hobbys" value="女孩">女孩
<input type="checkbox" name="hobbys" value="代码">代码
<input type="checkbox" name="hobbys" value="唱歌">唱歌
<input type="checkbox" name="hobbys" value="电影">电影
<br>
<input type="submit">
</form>
</div>
</body>
</html>
public class ServletRequest6 extends HttpServlet {
@Override
protected void doGet(javax.servlet.http.HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbys = req.getParameterValues("hobbys");
System.out.println("*************************");
//后台接收中文乱码问题 req.setCharacterEncoding("utf-8");
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.toString(hobbys));
System.out.println("*************************");
resp.sendRedirect("/fx1/success.jsp");
}
@Override
protected void doPost(javax.servlet.http.HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

浙公网安备 33010602011771号