JavaWeb-05-Servlet
1.Servlet简介servlet就是sun公司开动态web的一门技术sun公司在这些API中提供了一个接口叫做:servlet,如果想开发一个servlet程序,只需要完成两个小步骤:1.编写一个类,实现servlet接口2.把开发好的Java类部署web服务器中把实现了servlet接口的java程序叫做:servlet1.2HelloServletServlet接口Sun公司有两个默认的实
目录
1.Servlet简介
1.1 Servlet概述
1. servlet就是sun公司开动态web的一门技术
2.sun公司在这些API中提供了一个接口叫做:servlet,如果想开发一个servlet程序,只需要完成两个小步骤:
(1)编写一个类,实现servlet接口
(2)把开发好的Java类部署web服务器中
把实现了servlet接口的java程序叫做:servlet
1.2 HelloServlet
Servlet接口Sun公司有两个默认的实现类:HttpServlet,GenericServlet
1.构建一个普通的Maven项目,删掉里面的src目录,这个空的工程就是Maven主工程。
2.关于Maven父子工程的理解:
父项目中会有:
<modules>
<module>servlet-01</module>
</modules>
子项目会有:
<parent>
<artifactId>JavaWebStudy</artifactId>
<groupId>com.liu</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
父项目中的java子项目可以直接使用
son extends father
3.Maven环境优化
1.将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">
</web-app>
2.将maven的结构搭建完整
4.编写一个Servlet程序
1.编写一个普通类
2.实现servlet接口,这里我们直接继承HttpServlet
ps:ctrl+鼠标左键(查看源码)
public class HelloServlet extends HttpServlet {
//由于get或者post只是请求实现的不同方式,可以互相调用,业务逻辑都一样
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter writer=response.getWriter();//响应流
writer.print("Hello Servlet");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
5.编写Servlet的映射
为什么需要映射:我们写的是JAVA程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册我们写的Servlet,还需要给他一个浏览器能够访问的路径。
<!--注册Servlet-->
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.liu.servlet_01.HelloServlet</servlet-class>
</servlet>
<!--Servlet请求路径-->
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
6.配置Tomcat
注意:配置项目发布的路径就可以了。
7.启动测试,OK
1.3、Servlet原理
1.4 Mapping问题
1.一个Servlet可以指定一个映射路径
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.liu.servlet_01.HelloServlet</servlet-class>
</servlet>
2.一个Servlet可以指定多个映射路径(这几个路径指向同一个页面)
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello3</url-pattern>
</servlet-mapping>
3.一个Servlet可以指定通用映射路径
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
注意点:如果路径只写/*
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
ps:此时重启Tomcat,页面会优先加载服务器请求,而不会走静态资源路径。
4.可以自定义后缀实现请求映射(此时 * 前面不能加项目映射的路径)
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
5.优先级问题
指定了固定的映射路径优先级最高,如果找不到就会走默认的请求处理(案例自定义404);
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>com.liu.servlet_01.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
1.5 ServletContest
web容器在启动的时候,他会为web程序都创建一个对应的ServletContext对象,他代表了当前的web应用。
共享数据:我在这个servlet中保存的数据,可以在其他的servlet中取到。
一次性设置两个编码:
resp.setContentType("text/html; charset=utf-8");
Helloservlet(存放一个数据)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// this.getInitParameter() 初始化参数
// this.getServletConfig() Servlet配置
// this.getServletContext() Servlet上下文
ServletContext context=this.getServletContext();
String username="liuSir";//数据
context.setAttribute("username",username);//将一个数据保存在了ServletContext中,名字为:username 值为:username(键值对形式)
}
GetServlet(取出其他Servlet存放的数据)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context=this.getServletContext();
String username= (String) context.getAttribute("username");
//解决乱码问题
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
response.getWriter().print("username:"+username);
//解决编码问题:写在一行中的方法如下:
response.setContentType("text/html; charset=utf-8");
}
配置web.xml:
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.liu.servlet_01.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>GetServlet</servlet-name>
<servlet-class>com.liu.servlet_01.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GetServlet</servlet-name>
<url-pattern>/gets</url-pattern>
</servlet-mapping>
测试访问:如果先访问\hello路径,然后访问/gets路径,会发现页面输出有结果;如果先访问/gets路径,会发现页面只输出"username:"而没有后面的名字。
2.获取初始化参数
(1)
<!-- 配置一些初始化参数-->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
(2)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context=this.getServletContext();
String url= (String) context.getAttribute("url");
response.getWriter().print(url);
}
请求转发
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context=this.getServletContext();
RequestDispatcher requestDispatcher = context.getRequestDispatcher("/demo");//转发的请求路径
requestDispatcher.forward(request,response);//调用forWord实现请求转发
//上面两条语句合并就是:
context.getRequestDispatcher("/demo").forward(request,response);
}
4、读取资源文件
Properties:
在java目录下新建properties
在resource目录下新建properties
发现:都被打包到了同一个路径:classes,也叫classpath(类路径)
获取这个文件中的数据,需要定义一个流,设置好文件的路径。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties prop=new Properties();
prop.load(is);
String username=prop.getProperty("username");
String password=prop.getProperty("password");
response.getWriter().print(username+":"+password);
}
1.6 HttpServletResponse
web服务器接收客户端的http请求,针对这个请求,分别创建一个代表请求的HTTPServletRequest对象,代表响应的一个HttpServletResponse;
- 如果要获取客户端传过来的参数:找HttpServletRequest
- 如果要给客户端响应一些信息:找HttpServletResponse
1.6.1 简单分类
负责向浏览器发送数据的方法:
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
负责向浏览器发送响应头方法
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);
1.6.2 常见应用
1.向浏览器输出消息
2.下载文件
- (1)要获取下载文件的路径
- (2)下载的文件名
- (3)设置让浏览器能够支持下载我们需要的东西
- (4)获取下载文件的输入流
- (5)创建缓冲区
- (6)获取OutputStream对象
- (7)将FileOutputStream流写入到buffer缓冲区
- (8)使用OutputStream将缓冲区的数据输出到客户端。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//(1)要获取下载文件的路径
String realPath = "D:\\SystemStudy\\LiuStudy\\JavaWebStudy\\responseStudy\\src\\main\\resources\\cookie.jpg";
System.out.println("下载文件的路径:"+realPath);
//(2)下载的文件名
String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
// (3)设置让浏览器能够支持下载我们需要的东西,中文文件名需要使用URLEncoder编码
response.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 = response.getOutputStream();
//(7)将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区的数据输出到客户端。
while((len = in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
out.close();
}
1.6.3 验证码功能
后端实现:需要用到java图片类,生产一个图片。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//如何让浏览器5秒刷新一次
response.setHeader("refresh","3");
//在内存中创建一个图片
BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
//得到图片
Graphics2D g = (Graphics2D) image.getGraphics();//笔
//设置图片的背景颜色
g.setColor(Color.WHITE);
g.fillRect(0,0,80,20);
//给图片写数据
g.setColor(Color.blue);
g.setFont(new Font(null,Font.BOLD,20));
g.drawString(makeNum(),0,20);
//告诉浏览器这个请求用图片的方式打开
response.setContentType("image/jpeg");
//网站存在缓存,不让浏览器缓存
response.setDateHeader("expires",-1);
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");
//把图片写给浏览器
ImageIO.write(image,"jpg",response.getOutputStream());
}
//生成随机数
private String makeNum(){
Random random = new Random();
String num = random.nextInt(9999999) + "";
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 7-num.length(); i++) {
sb.append("0");
}
String s = sb.toString() + num;
return s;
}
1.6.4 实现重定向
一个web资源收到客户端请求后,它会通知客户端访问另外一个web资源,这个过程叫做重定向。
void sendRedirect(String var1) throws IOException;
测试:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
response.setHeader("Location","/responseStudy/image");
response.setStatus(302);
*/
//重定向
response.sendRedirect("/responseStudy/image");
}
面试题:请你聊聊重定向和转发的区别?
相同点:页面都会实现跳转。
不同点:
请求转发的时候,URL不会发生变化。307
重定向的时候,地址栏会发生变化。302
1.7 HttpServletRequest
HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,Http请求中的所有信息会被封锁到HttpServletRequest,通过这个HttpServletRequest的方法,获取客户端的所有信息。
1.7.1 获取前端传来的参数
ps:解决中文问题的代码,需要写在输出前面,不然会不起作用。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决中文乱码问题
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
String[] hobbys = request.getParameterValues("hobbys");
System.out.println("--------------------------------");
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.toString(hobbys));
System.out.println("--------------------------------");
//请求转发
//这里的 / 代表当前的web应用
request.getRequestDispatcher("/success.jsp").forward(request,response);
}
更多推荐
所有评论(0)