servlet文档2
HttpServletRequest
获取请求头API
| getMethod() | 获取请求的方式 | 
|---|---|
| getRequestURI() | 获取请求的uri(相对路径) | 
| getRequestURL() | 获取请求的url(绝对路径) | 
| getRemoteAddr() | 获取请求的地址 | 
| getProtocol() | 获取请求的协议 | 
| getRemotePort() | 获请请求的端口 | 
| getHeader(“Host”); | 获取请求的端口+地址 | 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("获取请求方式:"+request.getMethod());//GET
        System.out.println("获取请求的相对路径:"+request.getRequestURI());// /ServletDemo
System.out.println("获取请求的绝对方式:"+request.getRequestURL());// http://localhost:8081/ServletDemo
        System.out.println("获取http版本:"+request.getProtocol());// HTTP/1.1
        System.out.println("获取客户端的ip:"+request.getRemoteAddr());// 10.50.5.137
        System.out.println("获取当前请求地址+端口:"+request.getHeader("Host")); // 10.50.5.197:8081
    }
获取请求参数 API
| public String getParameter(String name) | 获取请求指定单个参数 | 
|---|---|
| public String[] getParameterValues(String name) | 获取请求指定多个参数 | 
| public Map<String,String[]> request.getParameterMap() | 获取页面所有提交过来的数据 | 
页面准备
    <form action="ServletDemo2" method="post">
        user:<input type="text" name="username"><br>
        sex:<input type="text" name="sex"><br>
        age:<input type="text" name="age"><br>
        爱好:<input type="checkbox" name="hobby" value="吃饭">吃饭
             <input type="checkbox" name="hobby" value="睡觉">睡觉
             <input type="checkbox" name="hobby" value="打豆豆">打豆豆<br>
        
			<input type="submit">
    </form>
代码实现
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //指定获取输入框内容,如果获取不到返回null
        String username = request.getParameter("username");
        String sex = request.getParameter("sex");
        String age = request.getParameter("age");
        System.out.println(username);
        System.out.println(sex);
        System.out.println(age);
        
        System.out.println("=========================");
        //如果是复选框,获取的值很多,指定获取只能获取第一个
        String hobby = request.getParameter("hobby");
        System.out.println(hobby);
        //request.getParameterValues("hobby"); 获取多个值
        String[] hobbies = request.getParameterValues("hobby");
        if(hobbies != null){
            for(String str : hobbies){
                System.out.println(str);
            }
        }
        
         System.out.println("==========================");
        //获取页面上所有提交的数据
        Map<String, String[]> map = request.getParameterMap();
        Set<String> set = map.keySet();
        for(String key : set){
            String[] values = map.get(key);
            for(String value : values){
                System.out.println(value);
            }
        }
    }
Post请求乱码的解决方案
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //解决post请求乱码问题
        request.setCharacterEncoding("utf-8");
        //指定获取输入框内容,如果获取不到返回null
        String username = request.getParameter("username");
        String sex = request.getParameter("sex");
        String age = request.getParameter("age");
        System.out.println(username);
        System.out.println(sex);
        System.out.println(age);
    }
Get请求乱码的解决方案
补充:
tomcat8 以上的版本都默认解决了get请求乱码问题,无需关注
        String username = request.getParameter("username");
	    //变量10个。
        username = new String(username.getBytes("iso8859-1"),"utf-8");
        System.out.println(username);
转发

| public RequestDispatcher getRequestDispatcher(String path) | 转发 | 
|---|
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //转发到指定页面
        // request.getRequestDispatcher("index.jsp").forward(request,response);
        //转发指定servlet
        request.getRequestDispatcher("ServletDemo").forward(request,response);
    }

转发:
	一次请求一次响应
	转发是服务器内部行为
	url不会发生改变
域对象
域:区域的含义;
什么是域对象
一个有作用范围的对象,可以在范围内共享数据
常见的域对象
* Request    范围是一次请求
* Session    范围是一次会话
* ServletContext(application)   范围是整个项目中,直到服务器关闭
域对象共有方法
| 方法 | 说明 | 
|---|---|
| void setAttribute(String name,Object obj) | 设置数据 | 
| Object getAttribute(String name) | 获取数据 | 
| void removeAttribute(String name) | 删除数据 | 
Request域
代表一次请求的范围,一般用于一次请求中转发的多个资源中共享数据
@WebServlet("/aServlet")
public class AServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("去就AServlet");
 
        //向request域对象中 存一个数据
        request.setAttribute("hanbao", "香辣鸡腿堡");
        // 链式编程横
        request.getRequestDispatcher("bServlet").forward(request, response);
    }
}
@WebServlet("/bServlet")
public class BServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("我就BServlet");
        //向request域对象中 获取数据
        String hanbao = (String) request.getAttribute("hanbao");
        System.out.println("hanbao:" + hanbao);
    }
}
ServletContext域
@WebServlet("/oneServlet")
public class OneServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 向servletContext域存数据
        ServletContext sc1 = request.getServletContext();
        sc1.setAttribute("user", "jack");
        System.out.println("我是oneServlet");
    }
}
@WebServlet("/twoServlet")
public class TwoServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 从servletContext域获取数据
        String user = (String) request.getServletContext().getAttribute("user");
        System.out.println("twoServlet获取数据:"+user);
    }
}
-  ServletContext生命周期 1. 何时创建? 项目加载时,创建 2. 何时销毁? 项目服务器关闭时,销毁 3. 作用范围? 与项目共存亡(多个servlet都可以操作它)
HttpServletResponse
常用API
| public void setStatus(int status) | 设置响应状码 | 
|---|---|
| public void [setHeader](mk:@MSITStore:F:\api\java_ee_api_中英文对照版.chm::/javax/servlet/http/HttpServletResponse.html#setHeader(java.lang.String, java.lang.String)) (Stringname,String value) | 设置响应该头 | 
向客户端浏览器,发数据,中文,乱码;
response.setCharacterEncoding(“utf-8”);
setContextType(“text/html;charset=utf-8”)
重定向

重定向: 客户端形行,一次请求,两次响应,把上一个url清空,重新响应了一个新的url,最终看到是新的url
 		重定向不能返回上一个url
实现方式: 		
	1:状态码302+响应地址
	2:response.sendRedirect()
   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //重定向
        response.setStatus(302);
        response.setHeader("Location","http://localhost:8081/index.jsp");
        //这种方法等价于以上两行代码
        response.sendRedirect("http://localhost:8081/index.jsp");
    }
重定向和转发的区别
重定向(redirect):属于客户端行为,一次请求两个url,url会在地址栏中显示,不能返回上一个历史记录,不能携带数据
转 发(forward): 属于服务器行为,一次请求一个url,url地址始终只有一个,可以携带数据
设置响应体
| setContentType(String charset) | 设置响应字符集(解决响应乱码问题) | 
|---|---|
| getWriter() | 把响应内容以流的形式输出(响应给浏览器) | 
| getHeader() | 设置响应头 | 
响应浏览内容
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置响应体及响应乱码
        response.setContentType("text/html;charset=utf-8");
        //响应给浏览器
        PrintWriter writer = response.getWriter();
        writer.println("<h2>servlet是动态网页技术</h2>");
        writer.println("<font style='color:red'>servlet高大尚</font>");
        response.getWriter().println("哈哈哈,我是从后台servlet响应给浏览器的");
    }
解决响应乱码问题
        //设置响应体及响应乱码
        response.setContentType("text/html;charset=utf-8");
自动刷新
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置响应体及响应乱码
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().println("对不起,你访问的资源不存在,3秒之后跳转到yiyan网站!!");
        response.setHeader("refresh","3;url=https://www.baidu.com");
    }
回顾html自动刷新:
    <meta http-equiv="refresh" content="3;url=https://www.baidu.com">
生成图片验证码
servlet代码
package cn.yanqi.web;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
@WebServlet(urlPatterns = "/Checkcode")
public class Checkcode extends HttpServlet {
    private static final int WIDTH = 100;	//设置验证码图片宽度
    private static final int HEIGHT = 30;	//设置验证码图片高度
    private static final int LENGTH = 4;	//设置验证码长度
    public static final int LINECOUNT=20;	//干扰线的数目
    //验证码的字符库
    private static final String str="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    //通过随机数取字符库中的字符组合成4位验证码
    private static Random random=new Random();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置数据类型为图片
        resp.setContentType("image/jpeg");
        //设置不进行缓存
        resp.setHeader("pragma", "no-cache");
        resp.setHeader("cache-control", "no-cache");
        resp.setHeader("expires", "0");
        //获取画笔
        BufferedImage image=new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_3BYTE_BGR);
        Graphics g=image.getGraphics();
        //设置背景颜色并绘制矩形背景
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, WIDTH, HEIGHT);
        //验证码的绘制
        String code=drawChar(g);
        System.out.println("验证码:"+code);
        //随机线的绘制
        for (int i=0;i<LINECOUNT;i++){
            drawLine(g);
        }
        //在session中存入当前的code码,便于验证
        req.getSession().setAttribute("code",code);
        //绘制图片
        g.dispose();
        //将图片输出到response中
        ImageIO.write(image, "JPEG", resp.getOutputStream());
    }
    //获取不同颜色
    public  Color getColor(){
        return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
    }
    //获取字体样式
    public Font getFont() {
        return new Font("Fixedsys", Font.CENTER_BASELINE, 20);
    }
    //绘制字符
    public String drawChar(Graphics g){
        String code="";
        g.setFont(getFont());
        for (int i=0;i<LENGTH;i++){
            char c=str.charAt(random.nextInt(str.length()));
            g.setColor(getColor());
            g.drawString(c+"", 20* i + 10, 20);
            code=code+c;
        }
        return code;
    }
    //绘制随机线
    public  void drawLine(Graphics g) {
        int x = random.nextInt(WIDTH);
        int y = random.nextInt(HEIGHT);
        int xl = random.nextInt(13);
        int yl = random.nextInt(15);
        g.setColor(getColor());
        g.drawLine(x, y, x + xl, y + yl);
    }
}
JS代码
    <form action="ServletDemo2" method="post">
        user:<input type="text" name="username"><br>
        sex:<input type="text" name="sex"><br>
        age:<input type="text" name="age"><br>
        爱好:<input type="checkbox" name="hobby" value="吃饭">吃饭
             <input type="checkbox" name="hobby" value="睡觉">睡觉
             <input type="checkbox" name="hobby" value="打豆豆">打豆豆<br>
        验证码:<input type="text" name="ckimg">
        		<img src="/Checkcode"  id="_img"><br>
        <input type="submit">
    </form>
    <script>
        window.onload = function () {
            var _img = document.getElementById("_img");
            _img.onclick = function () {
                var date = new Date();
                _img.src ="/Checkcode?"+date.getTime();
            };
        }
    </script>
JAVA代码
		//获取用户输入的验证码
        String _img = request.getParameter("ckimg");
        //获取服务器生成的验证码
        HttpSession session = request.getSession();
        String code = (String) session.getAttribute("code");
        //为了保证验证是有效的唯一,把上一个给清了
        session.removeAttribute("code");	
        //判断
        if(!_img.equalsIgnoreCase(code)){
            //提示用户
      		System.out.println("验证码不正确!");
            return;
        }
ode?"+date.getTime();
 };
 }
 
## JAVA代码
```java
		//获取用户输入的验证码
        String _img = request.getParameter("ckimg");
        //获取服务器生成的验证码
        HttpSession session = request.getSession();
        String code = (String) session.getAttribute("code");
        //为了保证验证是有效的唯一,把上一个给清了
        session.removeAttribute("code");	
        //判断
        if(!_img.equalsIgnoreCase(code)){
            //提示用户
      		System.out.println("验证码不正确!");
            return;
        }



















