Servlet
1.1简介
Servlet就是sun公司开发动态web的一门技术
Sun在这些API中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:
- 编写一个类,实现Servlet接口
- 把开发好的Java类部署到web服务器中。
把实现了Servlet接口的Java程序叫做,Servlet
1.2使用步骤
1).构建一个普通的Maven项目,删除其中的src目录,再在这个项目里面创建一个Module项目,这个空的module项目就是Maven的主工程,也可以将其看做父子工程,外面的Maven为父工程,里面的module为子工程,父项目中的java,子项目可以直接使用,父项目中导包后子项目不需要导包。
2).修改web.xml为最新的,将maven结构搭建完整
3).编写一个普通类,实现Servlet接口,也就是直接继承HttpServlet类
4).编写Servlet映射
我们写的java程序需要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册我们写的Servlet,还需要给他一个浏览器能够访问的路径。
在web.xml文件中,通过以下代码创建映射
<!--注册Servlet-->
<servlet>
<servlet-name>这里是虚拟路径映射,由自己写</servlet-name>
<servlet-class>这里是你写的java文件,格式为(包名.类名)</servlet-class>
</servlet>
<!--Servlet的请求路径-->
<servlet-mapping>
<servlet-name>和虚拟路径保持一致</servlet-name>
<url-pattern>/和虚拟路径保持一致</url-pattern>
</servlet-mapping>
5).配置Tomcat,配置项目发布的路径就可以了
6).启动
1.3 servlet的原理:
1.4 servlet的实现类:
servlet接口Sun公司定义了两个默认的实现类,GenericServlet,HttpServlet。
1.5 mapping问题
1.一个Servlet可以指定一个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
2.一个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>
3.一个Servlet可以指定通用映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
4.默认请求路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
5.指定一些后缀或者前缀等等
<!--可以自定义后缀实现请求映射
注意点,*前面不能加项目映射的路径
hello/sajdlkajda.qinjiang
只要以.qinjiang结尾的
-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.qinjiang</url-pattern>
</servlet-mapping>
6.优先级问题
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>com.kuang.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
1.6ServletContext
1)简介
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;
2)共享数据
我在这个Servlet中保存的数据,可以在另外一个servlet中拿到;
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String username = "aaa"; //数据
context.setAttribute("username",username); //将一个数据保存在了ServletContext中,名字为:username 。值 username
}
}
public class GetServlet 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().print("名字"+username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.kuang.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>getc</servlet-name>
<servlet-class>com.kuang.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getc</servlet-name>
<url-pattern>/getc</url-pattern>
</servlet-mapping>
//第一次通过hello执行存储username的操作,第二次通过getc执行获取username并将其输出的操作
3).利用ServletContext实现请求转发。
4).读取资源文件
不管是在在java目录下新建properties,还是在resources目录下新建properties,我们发现都被打包到了同一个路径下:classes,我们俗称这个路径为classpath。我们需要一个文件流
username=root12312
password=zxczxczxc
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/kuang/servlet/aa.properties");
Properties prop = new Properties();
prop.load(is);
String user = prop.getProperty("username");
String pwd = prop.getProperty("password");
resp.getWriter().print(user+":"+pwd);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>hello4</servlet-name>
<servlet-class>kuang.servlet.ServletDemo05</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello4</servlet-name>
<url-pattern>/hello4</url-pattern>
</servlet-mapping>
Response验证码实现
2.1创建一个页面用于生成随机数
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//如何让浏览器3秒自动刷新一次;
resp.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);
//告诉浏览器,这个请求用图片的方式打开
resp.setContentType("image/jpeg");
//网站存在缓存,不让浏览器缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
//把图片写给浏览器
ImageIO.write(image,"jpg", resp.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");
}
num = sb.toString() + num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>hello3</servlet-name>
<servlet-class>Test1.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello3</servlet-name>
<url-pattern>/hello3</url-pattern>
</servlet-mapping>
//通过hello3跳转到一个可以生成随机数的页面
重定向
3.1 概念
一个web资源B收到客户端A请求后,B他会通知A客户端去访问另外一个web资源C,这个过程叫重定向。
3.2举例
public class PageRedirect extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//方法一
//设置相应内容类型
resp.setContentType("text/html;charset=UTF-8");
//要重定向的位置
String site=new String("http://www.baidu.com");
//resp.sendRedirect();
resp.setStatus(resp.SC_MOVED_TEMPORARILY );
resp.setHeader("location",site);
//方法二
resp.sendRedirect("/r/img");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>helllo</servlet-name>
<servlet-class>Test.PageRedirect</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helllo</servlet-name>
<url-pattern>/bb</url-pattern>
</servlet-mapping>
3.3重定向和转发的区别
1)相同点
页面都会实现跳转
2)不同点
请求转发的时候,url不会产生变化 307
重定向时候,url地址栏会发生变化; 302
HttpServletRequest
4.1 概念
HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息;
4.2举例
package com.kuang.servlet;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class FormServlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理乱码
req.setCharacterEncoding("UTF-8");
//处理前端的请求
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("接收到的用户名:"+username+"\n密码:"+password+"\n爱好:");
String[] hobbies = req.getParameterValues("hobby");
for (String hobby : hobbies) {
System.out.println(hobby);
}
//重定向:服务器告诉客户端你应该请求另外一个地址; (地址栏会变)
//resp.sendRedirect("url");
//转发:服务器把这个请求转向另外一个Servlet去处理; (地址栏不会变)
//RequestDispatcher ,需要使用RequestDispatcher来进行处理,我们需要获得这个类
//参数就是他要转发到的页面
/*
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/success.jsp");
requestDispatcher.forward(req,resp);
*/
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}
}