2018年2月

HttpServletRequest

请求消息行

方法:
getMethod(); 获得请求方式
getRequestURL();返回客户端发出请求时的完整URL。
getRequestURI(); 返回请求行中的资源名部分。
getContextPath(); 当前应用的虚拟目录 。
getQueryString() ; 返回请求行中的参数部分。

请求消息头

String getHeader(String name); 根据头名称得到头信息值
Enumeration getHeaderNames(); 得到所有头信息name
Enumeration getHeaders(String name); 根据头名称得到相同名称头信息值

请求正文

与获取表单数据相关的方法

getParameter(name) 根据表单中name属性的名,获取value属性的值方法
getParameterValues(String name)专业为复选框取取提供的方法
getParameterNames() 得到表单提交的所有name的方法
getParameterMap 到表单提交的所有值的方法 //做框架用,非常实用
附录:框架的使用

导入commons-beanutils-1.8.3.jar和commons-logging-1.1.1.jar包
import org.apache.commons.beanutils.BeanUtils;//导包
BeanUtils.populate(new User(), request.getParameterMap());//调用方法

getInputStream 以字节流的方式得到所有表单数据

ServletInputStream sis = request.getInputStream();
        int len = 0;
    byte[] b = new byte[1024];
    while((len=sis.read(b))!=-1){
        
        System.out.println(new String(b, 0, len, "UTF-8"));
    }
        
    sis.close();

与操作非表单数据相关的方法(request也是一个域对象)

void setAttribute(String name, Object value);
Object getAttribute(String name);
Void removeAttribute(String name);

与请求转发相关的方法

//得到请求转发或请求包含的协助对象

RequestDispatcher getRequestDispatcher(String path)
forward(ServletRequest request, ServletResponse response) //转发的方法
include(ServletRequest request, ServletResponse response) //请求包含

与请求编码相关的方法:

  • 解决post方式编码
    request.setCharacterEncoding("UTF-8"); //告诉服务器客户端什么编码,只能处理post请求方式
  • 解决get方式编码

    String name = new String(name.getBytes(“iso-8859-1”),”UTF-8”);

HttpServletResponse

响应消息行

setStatus(int sc) 设置响应状态码

响应头

sendRedirect(String location) 请求重定向
setHeader(String name, String value) 设置响应头信息

  • 告知浏览器使用什么码表

    response.setHeader("content-type", "text/html;charset=UTF-8");
    • 告知客户端不缓存
    response.setHeader("pragma", "no-cache");
    response.setHeader("cache-control", "no-cache");
    response.setDateHeader("expires", 0);
    • Referesh刷新

    响应正文(主体)

    getWrite(); 字符输出流
    getOutputStream(); 字节输出流
    setCharacterEncoding(String charset) 告知服务器使用什么编码
    setContentType(String type)

首先导入ValidateCode.jar包
jar包的下载可以关注小宁博客公众号

实现类

public class ServletDemo4 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //告诉客户端不使用缓存
        response.setHeader("pragma", "no-cache");
        response.setHeader("cache-control", "no-cache");
        response.setIntHeader("expires", 0);
        
        
        ValidateCode vc = new ValidateCode(110, 25, 4, 9);
        String code = vc.getCode();//得到生成的字符
        vc.write(response.getOutputStream());
        
    }
}

网页代码

网页代码

<script type="text/javascript">
    function changeCode(){
        //得到图片元素
        var img = document.getElementsByTagName("img")[0];
        //img.setAttribute("src","/day09_00_HttpServletResponse/servlet/demo");//XML Dom 语法
        img.src = "/day09_00_HttpServletResponse/servlet/demo?time="+new Date().getTime();
    }
</script>
<img src="/day09_00_HttpServletResponse/servlet/demo4" onclick="changeCode()"/>
<a href="javascript:changeCode()" >看不清换一张</a>

自己用servlet实现0-9验证码,并且点击刷新,但是不建议还用,可以直接使用jar包自动生成
详情请见:servlet实现验证码

实现类

public class Demo extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
  
        code();
    }

    
    private void code HttpServletResponse response) throws IOException {
        int width = 110;
        int height = 25;
        //在内存中创建一个图像对象
        BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        
        //创建一个画笔
        Graphics g = img.getGraphics();
        
        //给图片添加背景色
        g.setColor(Color.PINK);//设置一个颜色
        g.fillRect(1, 1, width-2, height-2);//填充颜色
        
        //给边框一个色
        g.setColor(Color.RED);
        g.drawRect(0, 0, width-1, height-1);//设置边框的显示坐标
        
        //设置文本样式
        g.setColor(Color.BLUE);
        g.setFont(new Font("宋体", Font.BOLD|Font.ITALIC, 15));
        
        //给图片添加文本
        Random rand = new Random();
        int position = 20;
        for (int i = 0; i < 4; i++) {
            g.drawString(rand.nextInt(10)+"", position, 20);//给图片填充文本
            position+=20;
        }
        
        //添加9条干扰线
        for (int i = 0; i < 9; i++) {
            g.drawLine(rand.nextInt(width), rand.nextInt(height), rand.nextInt(width), rand.nextInt(height));
        }
        //将图片对象以流的方式输出的客户端
        ImageIO.write(img, "jpg", response.getOutputStream());
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

网页代码

<script type="text/javascript">
    function changeCode(){
        //得到图片元素
        var img = document.getElementsByTagName("img")[0];
        //img.setAttribute("src","/day09_00_HttpServletResponse/servlet/demo");//XML Dom 语法
        img.src = "/day09_00_HttpServletResponse/servlet/demo?time="+new Date().getTime();
    }
</script>
<img src="/day09_00_HttpServletResponse/servlet/demo4" onclick="changeCode()"/>
<a href="javascript:changeCode()" >看不清换一张</a>

通过servlet实现文件的下载,实例代码为下载一张jpg的图片

public class Demo extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //通过路径得到一个输入流
        String path = this.getServletContext().getRealPath("/WEB-INF/classes/img.jpg");
        FileInputStream fis = new FileInputStream(path);
        //创建字节输出流
        ServletOutputStream sos = response.getOutputStream();
        
        //得到要下载的文件名
        String filename = path.substring(path.lastIndexOf("\\")+1);
        
        //设置文件名的编码
        filename = URLEncoder.encode(filename, "UTF-8");//将不安全的文件名改为UTF-8格式
        
        //告知客户端要下载文件
        response.setHeader("content-disposition", "attachment;filename="+filename);
        response.setHeader("content-type", "image/jpeg");
        
        //执行输出操作
        int len = 1;
        byte[] b = new byte[1024];
        while((len=fis.read(b))!=-1){
            sos.write(b,0,len);
        }

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

ServletConfig

1.可以获取servlet配置信息

public class ServletConfigDemo1 extends HttpServlet {
    /*private ServletConfig config;
    public void init(ServletConfig config) throws ServletException {
        this.config = config;
    }*/
    public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
    /*String encoding = config.getInitParameter("encoding");//获得配置文件中的信息的
    System.out.println(encoding);*/
    //第二种方式
    String encoding = this.getServletConfig().getInitParameter("encoding");
    System.out.println(encoding);
    //第三种方式
    /*String encoding = super.getInitParameter("encoding");
    System.out.println(encoding);*/
}

       public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
        doGet(request, response);
    }

}

2.可以获得ServletContext对象

ServletContext

ServletContext: 代表的是整个应用。一个应用只有一个ServletContext对象。单实例。
作用:
域对象:在一定范围内(当前应用),使多个Servlet共享数据。
常用方法:
void setAttribute(String name,object value);//向ServletContext对象的map中添加数据
Object getAttribute(String name);//从ServletContext对象的map中取数据
void rmoveAttribute(String name);//根据name去移除数据
作用

  • 获取全局配置信息

String getInitParameter(String name); //根据配置文件中的key得到value

  • 获取资源路径

String getRealPath(String path);//根据资源名称得到资源的绝对路径。可以得到当前应用任何位置的任何资源。

  • 实现Servlet的转发。
    RequestDispatcher getRequestDispatcher(String path);//参数表示要跳转到位置

Servlet的三种创建方式

实现javax.servlet.Servlet接口

public class ServletDemo implements Servlet{
    //Servlet生命周期的方法
    //在servlet第一次被访问时调用
    //实例化
    public ServletDemo(){
        
    }
    //Servlet生命周期的方法
    //在servlet第一次被访问时调用
    //初始化
    public void init(ServletConfig arg0) throws ServletException {
        
        
    }
    //Servlet生命周期的方法
    //服务
    //每次访问时都会被调用
    public void service(ServletRequest arg0, ServletResponse arg1)
            throws ServletException, IOException {
        
    }
    
    //Servlet生命周期的方法
    //销毁
    public void destroy() {
        
    }

    public ServletConfig getServletConfig() {
        
        return null;
    }

    public String getServletInfo() {
        
        return null;
    }

继承javax.servet.GenericServlet类(适配器模式)

public class ServletDemo extends GenericServlet{

    @Override
    public void service(ServletRequest arg0, ServletResponse arg1)
            throws ServletException, IOException {
        
    }

}

继承javax.servlet.http.HttpServlet类(模板方法设计模式)

public class ServletDemo3 extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        
    }
    
}

注:解决线程安全问题的最佳办法,不要写全局变量,而写局部变量。

实例化

客户端发送请求后首先判断是否存在Servlet实例,如果没有存在创建Servlet实例(Servlet的构造方法)。
构造方法

public ServletDemo(){
    
}

初始化

如果存在Servlet实例,则开始其初始化阶段,执行器初始化方法(init()方法)。
init 方法的定义如下:

public void init() throws ServletException {
  // 初始化代码...
}

服务

第三阶段是响应客户端请求阶段,调用service()方法,根据提交方式选择执行doGet()方法或者doPost()方法。
下面是该方法的特征:

public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException{

}
  • doGet() 方法

GET 请求来自于一个 URL 的正常请求,或者来自于一个未指定 METHOD 的 HTML 表单,它由 doGet() 方法处理。

public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
    // Servlet 代码
}
  • doPost() 方法

POST 请求来自于一个特别指定了 METHOD 为 POST 的 HTML 表单,它由 doPost() 方法处理。

public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
    // Servlet 代码
}

销毁

最后是销毁阶段,程序结束或者是服务器停止,调用其销毁方法(destroy()方法)。
destroy 方法定义如下所示:

  public void destroy() {
    // 终止化代码...
  }

servlet

servlet 是运行在 Web 服务器中的小型 Java 程序(即:服务器端的小应用程序)。servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求。

执行过程

  1. 客户端发送请求(以Get方式或者Post方式发送请求)http://localhost:8080/day08servlet/demo
  2. 在web.xml中找到

      <servlet-name>servletDemo</servlet-name>
      <url-pattern>/demo</url-pattern>

注:第一条中的请求路径对应的就是url-pattern中的请求路径。找到要执行的servletDemo,对应第三条中的servlet-name。
3.同样是在web.xml中,寻找

<!-- 创建一个servelet实例 -->
  <servlet>
      <servlet-name>servletDemo</servlet-name>
      <servlet-class>com.sunxiaoning.servlet.ServletDemo</servlet-class>
      <load-on-startup>2</load-on-startup>
  </servlet>

注:第二条中的servlet-name对应第三条中的servlet-name,并且我们可以根据servlet-class找到对应的类。load-on-startup表示在当前服务启动时自动创建,数字越小优先级越高,不建议使用0。
4.根据servlet-class我们找到请求对应的类信息,根据请求方式确定调用doGet()方法或者doPost()方法

Myeclipse的常用快捷键的总结

ctrl+shift+M 导入未引用的包
ctrl+w 关闭单个窗口
F3 跳转到类、变量的声明
F11 运行上次程序
Ctrl + F11 调试上次程序
Alt + 回下一个编辑点
ctrl+shift+T 查找工程中的类
Ctrl+D: 删除当前行
Ctrl+Alt+↓ 复制当前行到下一行(复制增加)
Ctrl+Alt+↑ 复制当前行到上一行(复制增加)
Alt+↓ 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了)
Alt+↑ 当前行和上面一行交互位置(同上)
Alt+← 前一个编辑的页面
Alt+→ 下一个编辑的页面(当然是针对上面那条来说了)
Alt+Enter 显示当前选择资源(工程,or 文件 or文件)的属性
Shift+Enter 在当前行的下一行插入空行(这时鼠标可以在当前行的任一位置,不一定是最后)
Shift+Ctrl+Enter 在当前行插入空行(原理同上条)
Ctrl+Q 定位到最后编辑的地方
Ctrl+L 定位在某行 (对于程序超过100的人就有福音了)
Ctrl+M 最大化当前的Edit或View (再按则反之)
Ctrl+/ 注释当前行,再按则取消注释
Ctrl+O 快速显示 OutLine
Ctrl+T 快速显示当前类的继承结构
Ctrl+W 关闭当前Editer
Ctrl+K 参照选中的Word快速定位到下一个
Ctrl+E 快速显示当前Editer的下拉列表
Ctrl+/(小键盘) 折叠当前类中的所有代码
Ctrl+×(小键盘) 展开当前类中的所有代码
Ctrl+Shift+E 显示管理当前打开的所有的View的管理器(可以选择关闭,激活等操作)
Ctrl+J 正向增量查找(按下Ctrl+J后,你所输入的每个字母编辑器都提供快速匹配定位到某个单词,如果没 有,则在stutes line中显示没有找到了,查一个单词时,特别实用,这个功能Idea两年前就有了)
Ctrl+Shift+J 反向增量查找(和上条相同,只不过是从后往前查)
Ctrl+Shift+F4 关闭所有打开的Editer
Ctrl+Shift+X 把当前选中的文本全部变为小写
Ctrl+Shift+Y 把当前选中的文本全部变为小写
Ctrl+Shift+F 格式化当前代码
Ctrl+Shift+P 定位到对于的匹配