分类 编程语言 下的文章

自己用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()方法

XML(eXtensible Markup Language):可扩展标记语言
版本:version="1.0"
特性:
可扩展:所有的标签都是自定义的。
功能:数据存储,配置文件,数据传输。

html与xml区别:

  • html语法松散,xml语法严格
  • html做页面展示,xml做数据存储
  • html所有标签都是预定义的,xml所有标签都是自定义的
    xml语法

文档声明:

1.必须写在xml文档的第一行。
2.写法:<?xml version="1.0" ?>
3.属性:
(1)version:版本号 固定值 1.0
(2)encoding:指定文档的码表。默认值为 iso-8859-1
(3)standalone:指定文档是否独立 yes 或 no(一般不写)

元素:xml文档中的标签
1.文档中必须有且只能有一个根元素
2.元素需要正确闭合。
3.元素需要正确嵌套
4.元素名称要遵守:元素名称区分大小写,并且数字不能开头。

文本:
1.转义字符:&gt;等。
CDATA: 里边的数据会原样显示 <![CDATA[ 数据内容 ]]>

属性:属性值必须用引号引起来。单双引号都行
注释:<!-- -->
处理指令:现在基本不用<?xml-stylesheet type="text/css" href="1.css"?>
xml约束:约束就是xml的书写规则

约束的分类:
1.dtd:
dtd分类:
(1)内部dtd:在xml内部定义dtd
(2)外部dtd:在外部文件中定义dtd
(3)本地dtd文件:<!DOCTYPE students SYSTEM "student.dtd">
(4)网络dtd文件:<!DOCTYPE students PUBLIC "名称空间" "student.dtd">
2.schema:
导入xsd约束文档:
(1)编写根标签
(2)引入实例名称空间 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
(3)引入名称空间 xsi:schemaLocation="http://www.itcast.cn/xml student.xsd"
(4)引入默认的名称空间

概念

JDBC(java database connectivity )SUN公司提供的一套操作数据库的标准规范。是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。

  • JDBC与数据库驱动的关系:接口与实现的关系。
  • JDBC规范(掌握四个核心对象):

    DriverManager:用于注册驱动
    Connection: 表示与数据库创建的连接
    Statement: 操作数据库sql语句的对象
    ResultSet: 结果集或一张虚拟表

  • 实现JDBC操作

    1、注册驱动
    2、创建连接
    3、得到执行sql语句的Statement对象
    4、执行sql语句,并返回结果
    5、处理结果
    6、关闭资源

常用的类和接口

java.sql.Drivermanager类

作用:创建连接

1.注册驱动

DriverManager.registerDriver(new com.mysql.jdbc.Driver());不建议使用
原因
导致驱动被注册2次,并且强烈依赖数据库的驱动jar
解决办法:Class.forName("com.mysql.jdbc.Driver");

2.与数据库建立连接
方式一:(常用)

static Connection getConnection(String url, String user, String password) 

试图建立到给定数据库 URL 的连接。
示例:
getConnection("jdbc:mysql://localhost:3306/user", "root", "root");
注意:
URL:SUN公司与数据库厂商之间的一种协议。
jdbc:mysql://localhost:3306/user
协议 子协议 IP :端口号 数据库
mysql: jdbc:mysql://localhost:3306/user 或者 jdbc:mysql:///user(默认本机连接)
oracle: jdbc:oracle:thin:@localhost:1521:sid

方式二:

Properties info = new Properties();//要参考数据库文档
info.setProperty("user", "root");
info.setProperty("password","root");
getConnection(String url, Properties info);
getConnection(String url);

方式三:

DriverManager.getConnection("jdbc:mysql://localhost:3306/user?user=root&password=root");

java.sql.Connection接口

作用:建立一个连接
注意:接口的实现在数据库驱动中。所有与数据库交互都是基于连接对象的。
方法:Statement createStatement(); //创建操作sql语句的对象

java.sql.Statement接口

作用:操作sql语句,并返回相应结果的对象
注意:接口的实现在数据库驱动中。用于执行静态 SQL 语句并返回它所生成结果的对象。
方法:
1.ResultSet executeQuery(String sql) 根据查询语句返回结果集。只能执行select语句。
2.int executeUpdate(String sql) 根据执行的DML(insert update delete)语句,返回受影响的行数。
3.boolean execute(String sql) 此方法可以执行任意sql语句。返回boolean值,表示是否返回ResultSet结果集。仅当执行select语句,且有返回结果时返回true, 其它语句都返回false;

注意:为防止SQL注入一般使用preparedStatement方法
preparedStatement:预编译对象, 是Statement对象的子类。
特点:

  • 性能要高;
  • 会把sql语句先编译;
  • sql语句中的参数会发生变化,过滤掉用户输入的关键字。

java.sql.ResultSet接口

作用:处理结果集
方法及作用

1.封装结果集的

  • 提供一个游标,默认游标指向结果集第一行之前。
  • 调用一次next(),游标向下移动一行。
  • 提供一些get方法。

封装数据的方法
Object getObject(int columnIndex); 根据序号取值,索引从1开始
Object getObject(String ColomnName); 根据列名取值。

2.将结果集中的数据封装到javaBean中

java的数据类型与数据库中的类型的关系

byte          tityint
short         smallint
int           int
long          bigint
float         float
double        double
String        char varchar 
Date         date

常用方法

  • boolean next()将光标从当前位置向下移动一行
  • int getInt(int colIndex)以int形式获取ResultSet结果集当前行指定列号值
  • int getInt(String colLabel)以int形式获取ResultSet结果集当前行指定列名值
  • float getFloat(int colIndex)以float形式获取ResultSet结果集当前行指定列号值
  • float getFloat(String colLabel)以float形式获取ResultSet结果集当前行指定列名值
  • String getString(int colIndex)以String 形式获取ResultSet结果集当前行指定列号值
  • String getString(String colLabel)以String形式获取ResultSet结果集当前行指定列名值
  • Date getDate(int columnIndex);以int形式获取Date结果集当前行指定列名值
  • Date getDate(String columnName); 以Date形式获取Date结果集当前行指定列名值
  • void close()关闭ResultSet 对象

可移动游标的方法

  • boolean next() 将光标从当前位置向前移一行。
  • boolean previous() 将光标移动到此 ResultSet 对象的上一行。
  • boolean absolute(int row) 参数是当前行的索引,从1开始,根据行的索引定位移动的指定索引行。
  • void afterLast() 将光标移动到末尾,正好位于最后一行之后。
  • void beforeFirst() 将光标移动到开头,正好位于第一行之前。

关闭资源

对象名.close();

注意:从小向大关闭。

不需要main方法,直接对其他方法进行测试,只要选中测试方法,直接运行,就可以显示要测试的方法的对与错,需要在测试方法前面写上@Test,然后导包。就可以运行了。需要注意的是:测试方法要求:不能有返回值,不能有参数。下面是小编写的一个小案例:

package com.sunxiaoning.demo;
import org.junit.Assert;
import org.junit.Test;
public class TestCalc {

    @Test
    public void test1() {
        Calc c = new Calc();
        Assert.assertEquals(9,c.add(3, 6));//第一个参数是期望值,第二个参数,实际值
    }
    @Test
    public void test2() {
        Calc c = new Calc();
        Assert.assertEquals(3,c.div(10, 3),0.4);//第一个参数是期望值,第二个参数,实际值,第三个参数浮动值
    }

}
class Calc {
    public int add(int a,int b) {
        return a+b;
    }
    public double div(double a,double b) {
        return a/b;
    }
}

超链接的优化写法

`<base target="_blank">`   让所有的超链接都在新窗口打开

文本格式化标签

语义标签建议使用
文本加粗标签<strong></strong> <b></b><strong></strong>
文本倾斜标签<em></em> <i></i><em></em>
删除线标签<del></del> <s></s><del></del>
下划线标签<ins></ins> <u></u><ins></ins>

列表

无序列表

<ul>
     <li></li>    列表项
     <li></li>
     <li></li>
</ul>

有序列表

 <ol>
    <li></li>    列表项
    <li></li>
    <li></li>
 </ol>

自定义列表

    <dl>
      <dt></dt>    小标题
      <dd></dd>   解释标题
      <dd></dd>   解释标题
    </dl>

设置icon图标

    <link rel="icon" href="" />

表格

属性

    <caption></caption>    表头  
    cellspacing=”2”    单元格与单元格的距离
    cellpadding=”2”    内容距边框的距离
    colspan=”2”  合并同一行上的单元格
    rowspan=”2”  合并同一列上的单元格
    Valign=”top   |  middle   |  bottom”  垂直对齐方式

表单

输入框属性

    maxlength="10"    限制输入字符长度
    readonly=”readonly”  将输入框设置为只读状态(不能编辑)
    disabled="disabled"  输入框未激活状态(不能编辑,不能使用)
    name="username"   输入框的名称
    value="name"     将输入框的内容传给处理文件
    placeholder   表单提示,兼容性不好,一般不用

下拉列表属性

    multiple=”multiple”  将下拉列表设置为多选项
    <optgroup label=””></optgroup>  对下拉列表进行分组。Label=””  分组名称。

表单信息分组

    <fieldset></fieldset>    对表单信息分组
    <legend></legend>      表单信息分组名称

h5控件

    <input type="url"> url控件
    <input type="date"> 日期控件
    <input type="time"> 时间控件
    <input type="email"> email控件
    <input type="time"> 时间控件
    <input type="number" step="5"> 时间控件,step步进值
    <input type="range" step="5"> 滑块控件,step步进值