Giter Club home page Giter Club logo

myblog's People

Contributors

sunnyandgood avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

pessimistictime

myblog's Issues

数组全排列(无重复)

public class Test {
	public static void permutation(char[] strE, int begin) {
		if(begin == strE.length){
			System.out.println(new String(strE));
		}else{
			for(int i=begin;i<strE.length;i++){
				if(isSwap(strE,begin,i)){
					char temp = strE[i];
					strE[i] = strE[begin];
					strE[begin] = temp;
					
					permutation(strE,begin+1);
					
					temp = strE[i];
					strE[i] = strE[begin];
					strE[begin] = temp;
				}
			}
		}
	}

	public static boolean isSwap(char[] strE, int begin, int end) {
		for(int i=begin;i<end;i++) {
			if(strE[i]==strE[end]) {
				return false;
			}
		}
		return true;
	}
}

工具、学习、练习

servlet

1、创建form表单,确定提交方式
2、创建servlet类:创建类,继承HttpServlet,该类在servlet-api.jar
 复写doGet/doPost方法
3、配置请求映射
  <servlet>
   <!--servlet名称,与配置文件中的<servlet-mapping>标签中的servlet-name匹配-->
   <servlet-name>servlet01</servlet-name>
   <!--servlet类的全名称,原理:Java反射机制-->
   <servlet-class>com.wxkj.servlet.action.ServletAction</servlet-class>
  </servlet>
  <servlet-mapping>
    <!--servlet名称,与配置文件中的<servlet>标签中的servlet-name匹配-->
   <servlet-name>servlet01</servlet-name>
   <!--响应请求,当浏览器请求到达时,此处首先匹配-->
   <url-pattern>/form01</url-pattern>
  </servlet-mapping>
4、表单的method属性决定了servlet类对象呗访问的是doGet还是doPost
 method属性值为get,则访问doGet
 method属性值为post,则访问doPost
 超链接相当于显示提交,访问doGet
 浏览器地址栏直接敲请求,也为get方式
5、servlet生命周期 
 init()初始化方法,当servlet被创建时调用,一般做初始化处理
 service(HttpServletRequest arg0, HttpServletResponse arg1)
  整个生命周期过程中调用的方法,所有的请求都走service方法
  如果service方法中调用父类service方法,则根据提交方式自动分发给doGet/doPost方法
 destroy()销毁,当servlet被销毁时调用,一般做警告处理
6、<load-on-startup>0</load-on-startup>
 当服务器启动时创建servlet实例
 标签包裹的部分为整数类型数字
 当数字大于等于0时,数字越小,创建越早
 当数字小于0时,等同于不写该标签 
7、自定义方法的使用
 创建自定义方法,在service方法中进行调用
 在请求中添加状态参数,service根据状态参数来决定调用哪一个自定义方法

Java字符串分割的三种方法

一、StringTokenizer方法

Java中substring方法可以分解字符串,返回的是原字符串的一个子字符串。如果要讲一个字符串分解为一个一个的单词或者标记,可用StringTokenizer来解决

StringTokenizer的三个构造方法:

  1. StringTokenizer(String str)。默认以” \t\n\r\f”(前有一个空格,引号不是)为分割符。
源码:
public StringTokenizer(String str) {
	this(str, ” \t\n\r\f”, false);
}

> For example

import java.util.StringTokenizer;

public class Test {

	public static void main(String[] args) {  
		StringTokenizer stringTokenizer = new StringTokenizer("www hao123 com");  
		 while(stringTokenizer.hasMoreElements()){  
			 System.out.println("print:" + stringTokenizer.nextToken());  
		 }  
	} 
}
输出:
print:www
print:hao123
print:com

2.StringTokenizer(String str, String delim)。指定delim为分割符。

> For example

import java.util.StringTokenizer;

public class Test  {

	public static void main(String[] args) {  
		StringTokenizer stringTokenizer = new StringTokenizer("www.hao123.com", ".1");  
		 while(stringTokenizer.hasMoreElements()){  
			 System.out.println("print:" + stringTokenizer.nextToken());  
		 }  
	}  
}

输出:
print:www
print:hao
print:23
print:com

3.StringTokenizer(String str, String delim, boolean returnDelims)。returnDelims为true的话则delim分割符也被视为标记。

> For example

import java.util.StringTokenizer;

public class Test {

	public static void main(String[] args) {  
		  StringTokenizer stringTokenizer = new StringTokenizer("www.hao123.com", ".", true);  
		  while(stringTokenizer.hasMoreElements()){  
		  System.out.println("print:" + stringTokenizer.nextToken());  
		  }  
	} 
	
}
输出:
print:www
print:.
print:hao123
print:.
print:com

二、String.split()方法

在java.lang包中有String.split()方法,返回是一个数组。

1、“.”和“|”都是转义字符,必须得加"\";
  如果用“.”作为分隔的话,必须是如下写法:String.split("\\."),这样才能正确的分隔开,不能用String.split(".");
如果用“|”作为分隔的话,必须是如下写法:String.split("\\|"),这样才能正确的分隔开,不能用String.split("|");

2、如果在一个字符串中有多个分隔符,可以用“|”作为连字符,比如:“acount=? and uu =? or n=?”,把三个都分隔出来,可以用String.split("and|or");

3、public String[] split(String regex,int limit)根据匹配给定的正则表达式来拆分此字符串。
  此方法返回的数组包含此字符串的每个子字符串,这些子字符串由另一个匹配给定的表达式的子字符串终止或由字符串结束来终止。数组中的子字符串按它们在此字符串中的顺序排列。如果表达式不匹配输入的任何部分,则结果数组只具有一个元素,即此字符串。

4、public string[] split(string regex)
  这里的参数的名称是 regex ,也就是 regular expression (正则表达式)。这个参数并不是一个简单的分割用的字符,而是一个正则表达式,

三、substring方法

  1. substring(int beginIndex)该子字符串从beginIndex处的字符开始,直到此字符串末尾。
  2. substring(int beginIndex, int endIndex)该子字符串从指定的 beginIndex 处开始,直到索引 endIndex – 1 处的字符。注意:其它一些语言第二个参数往往代表长度,JAVA不一样。该子字符串的长度为 endIndex-beginIndex。
    > For example
public class Test {

	public static void main(String[] args) {  
		  String a = "www.hao123.com";
		  System.out.println(a);
		  String b = a.substring(2);
		  System.out.println(b);
		  String c = a.substring(1,10);
		  System.out.println(c);
		  String d = a.substring(6, a.length()); 
		  System.out.println(d);
	}  
}

输出:
www.hao123.com
w.hao123.com
ww.hao123
o123.com

注:beginIndex不能为负数,endIndex不能超出字符串长度,否则会抛出StringIndexOutOfBoundsException异常

四、js的substring方法

语法: String.substring(start, end);返回一个从start开始到end(不包含end)的子字符串。

var str="abcdefgh";
document.write(str.substring(0,1));//return:a
document.write(str.substring(2,5));//return:cde
document.write(str.substring(7,8));//return:h

js的substring()方法与java的比较相似,但js的substring()需要注意一下几点:

  1. start不一定就是第一个参数,end也不一定就是第二个参数,substring(3,1)时,开始位置是1,结束位置是3;
  2. 当要返回的子字符串是从开始位置到结束时,end的值必须大于等于字符串的长度,如上边的str.substring(7,8),按照索引从0开始算的话end的最大值为7,但这边却用8,当然,使用大于8的数返回的结果也是一样的。

津巴布韦

津巴布韦
由于计划经济失败,津巴布韦称为世界上通胀率最高的国家。这里的物价即使在一天中也会持续上涨,所以必须实时更新物品价格。例如:1个鸡蛋的价格为35亿津巴布韦元,所以超市做了每位数字的活动标价牌。
钟旭在穆加贝超市打工,有一天遇到了一位比较麻烦的客人。这位客人要退回刚才买走的鸡蛋,但是他不仅丢失了发票,而且连购买鸡蛋的数量也记不清了。鸡蛋价格已经在此期间上涨了1次,所以广告牌上已经写上新的价格。辛亏钟旭还记得如下两件事情。
1)最近一次价格上涨的时候,钟旭只是交换了塑料板的顺序。也就是说,没有添加其他塑料板,也没有去掉过广告牌中的塑料板。
2)看到最近一次上涨的价格时,钟旭心里曾经想过,“哇,这些钱刚好能购买m个糖果”。所以,最后的鸡蛋价格是m的倍数。(因为糖果的价格已经上涨,所以不能计算出鸡蛋的价格了)。
输入
第一行输入测试用例的个数C(C<=50)。之后的C行里面每行输入两个自然数e和m(1<=e<=1014,2<=m<=20)。当前鸡蛋的价格不能以0开始,但是之前的价格可以以0开始。
输出
每个测试用例在1行内输出可能的价格个数除以1 000 000 007的余数。

示例输入值:
4
321 3
123 3
422 2
12738173912 7
示例输出值
5
0
2
11033
示例输入输出值的说明
第一个示例输入值:以前鸡蛋的价格可能是123元、132元、213元、231元、312元。
第二个示例输入值:无论怎样重新排列123元的数字,结果都会比123元大,故无解。
第三个示例输入值:224元和242元是可能的价格。
第四个示例输入值:鸡蛋简直太贵了。

一、C++/C实现

#include<iostream>
#include<string.h>
#include<stdlib.h>
#include <sstream>
using namespace std;

long long countNum = 0;
bool IsSwap(char* pBegin, char* pEnd)
{
    char* p;
    for (p=pBegin; p<pEnd; p++)
    {
        if (*p == *pEnd)
            return false;
    }
    return true;
}

void Permutation(char* pStr, char* pBegin,char *pre_str,int m)
{
    if (*pBegin == '\0')
    {
        if (strcmp(pre_str, pStr) > 0)//如果pre_str>pStr则返回正数
        {
            stringstream ss;
            long long ll;
            ss<<pStr;
            ss>>ll;
            if(ll%m == 0)
            {
                countNum++;
            }
            //countNum++;
            /*if (strtol(pStr, NULL, 10)%m == 0)//将pStr转换为10进制数
            {
                countNum++;
            }*/
        }
    }
    else
    {
        for (char* pCh = pBegin; *pCh!='\0'; pCh++)
        {
            if( IsSwap(pBegin,pCh) )
            {
                char temp = *pCh;
                *pCh = *pBegin;
                *pBegin = temp;

                Permutation(pStr, pBegin+1,pre_str,m);

                temp = *pCh;
                *pCh = *pBegin;
                *pBegin = temp;
            }
        }
    }
}

int main()
{
    long long out[50];
    char strE[100];
    int time,m;
    char pre_str[100] = {0};
    cout<<"The time is: ";
    cin>>time;
    cout<<endl;

    cout<<"The original strings is: "<<endl;
    for (int i = 0; i < time; i++)
    {
        cin>>strE>>m;
        strcpy(pre_str, strE);
        Permutation(strE,strE,pre_str,m);
        out[i] = countNum%1000000007;
        countNum = 0;
    }

    cout<<"After permutation select, the price possible number  is: "<<endl;
    for (int i = 0; i < time; i++)
    {
        cout<<out[i]<<endl;
    }
    return 0;
}

二、java实现

import java.math.BigInteger;
import java.util.Scanner;
public class Zimbabwe {
	private static double count = 0; 
	
	public static void main(String[] args) {
		Zimbabwe zimbabwe = new Zimbabwe();
		double value[] = new double[50];
		char strE[] = new char[100]; 
		int time;
		int m;
		
		System.out.print("The time is: ");
		
		Scanner input = new Scanner(System.in);
		time = input.nextInt();
		System.out.println();
		
		
		for(int i=0;i<time;i++){
			char pre_str[] = new char[100];
			String str = input.next();
			m = input.nextInt();
			
			strE = str.toCharArray();
			pre_str = zimbabwe.copyOf(strE);
			zimbabwe.permutation(strE,0,pre_str,m);
			value[i] = count%1000000007;
			count = 0;
		}
		
		System.out.println("The original strings is: ");
		
		for(int i=0;i<time;i++){
			String str = String.valueOf(value[i]);
			String arr[] = str.split("\\.");
			System.out.println(arr[0]);
		}
	}

	private char[] copyOf(char[] strE) {
		int length = strE.length;
		char[] str = new char[length];
		for(int i=0;i<length;i++){
			str[i] = strE[i];
		}
		return str;
	}

	private void permutation(char[] strE, int begin, char[] pre_str, int m) {
		Zimbabwe zimbabwe = new Zimbabwe();
		if(begin == strE.length){
			if(zimbabwe.compare(pre_str,strE)){
				if(zimbabwe.doubleParseInt(strE, m)){//zimbabwe.bigIntegerParseInt(strE, m)
					count++;
				}
			}
		}else{
			for(int i=begin;i<strE.length;i++){
				if(zimbabwe.isSwap(strE,begin,i)){
					char temp = strE[i];
					strE[i] = strE[begin];
					strE[begin] = temp;
					
					zimbabwe.permutation(strE,begin+1,pre_str,m);
					
					temp = strE[i];
					strE[i] = strE[begin];
					strE[begin] = temp;
				}
			}
		}
	}

	private boolean doubleParseInt(char[] strE,int m) {
		String str = new String(strE);
		double num = Double.valueOf(str);
		if(num%m==0.0)
			return true;
		return false;
	}
	
	private boolean bigIntegerParseInt(char[] strE,int m){
		String str = new String(strE);
		BigInteger bigNum = new BigInteger(str);
		BigInteger bigM = BigInteger.valueOf(m);
		if(bigNum.remainder(bigM) != null)
			return true;
		return false;
	}

	private boolean numParseInt(char[] strE,int m) {
		double value = 0.0;
		for(int i=0;i<strE.length;i++) {
			value = value+strE[i]*Math.pow(10.0,strE.length-1-i);
		}
		if(value%m==0.0)
			return true;
		return false;
	}

	private boolean isSwap(char[] strE, int begin, int end) {
		for(int i=begin;i<end;i++) {
			if(strE[i]==strE[end]) {
				return false;
			}
		}
		return true;
	}

	private boolean compare(char[] str1, char[] str2) {
		String string1 = new String(str1);
		String string2 = new String(str2);
		if(string1.compareTo(string2) > 0){
			return true;
		}
		else {
			return false;
		}
	}
}

比较两个数组的大小

例如:int[] a=new int[]{123,445,567};
     int[] b=new int[]{123,556,677};

比较:  返回 -1,0,1
数组第一个数大,数组大
如果第一个相等,比较第二个,第二个大,数组大
如果第二个相等,比较第三个,第三个大,数组大。。。。。。

代码如下

/**
  * @author wrh
  */
 public class Test {
     public static void main(String[] args) {
    	 int a[] = {123,445,567};
         int b[] = {123,556,677};
      
         int value = compare1(a,b,max(a.length,b.length));
         System.out.println(value);
     }
     //用while循环
     public static int compare1(int[] a, int[] b, int len) {
           int i = 0;
	   while(i<len)
	  {
		if(a[i]>b[i])
			return 1;
		if(a[i]<b[i])
			rturn -1;
		i++;
	  }
	  return 0;
    }
      //递归实现
     public static int compare2(int[] a, int[] b, int len)
     {
    	int length = max(a.length,b.length);
    	int first = length-len;
        if(a[first]>b[first])
        {
            return 1;
        }
        else if(a[first]<b[first])
        {
            return -1;
        }
        else if(len==1)
        {
            return 0;
        }
        else
        {
            return compare2(a,b,len-1);
        }
     }
      
    public static int max(int length1, int length2) {
	   return (length1>length2)?length1:length2;
    }
}

字符串、数组、数字之间的转换

  1. 将数字转换为字符串:String str = String.valueOf(number);
  2. 字符串转换为数字(前提是字符串是纯数字):int number=Integer.parseInt(str);
  3. 获取大数字的长度:先将大数字转换为字符串,再获取长度:
    int length =String.valueOf(number).length();
  4. 将大数字或字符串存进数组:
    如果是大数字,则需要转换为字符串,字符串则直接进行存储:
public class Test {

	public static void main(String[] args) {
		double number = 123456;
		String str = String.valueOf(number);  //转换为字符串  
	    int length = str.length();  
	    String strNumber[] = new String[length];  
	
	    for (int i = 0; i < length; i++) {  
	        strNumber[i] = str.substring(i, i + 1);
	    }
	    for (int i = 0; i < length; i++) {  
	        System.out.println(strNumber[i]);
	    }
	}  
}

5、字符串转为十进制的数double num = Double.valueOf(String str);

For example

public class Test {

	public static void main(String[] args) {
		String str1 = new String("12738173912");
		double num = Double.valueOf(str1);
		double value = num%7.0;
		String str2 = String.valueOf(value);
		String arr[] = str2.split("\\.");
		System.out.println(arr[0]);
	}  
}

6、数组转换为字符串的方法

方法一:直接用数组转字符串方法效果如下

char[] c1 = new char[]{'a','d','s'};
return = Arrays.toString(c1);

输出效果:[a, d, s]

方法二:使用StringBuffer转换

char[] c4 = new char[]{'a','d','s','a','d','s'};
StringBuffer sb = new StringBuffer();
for(int i = 1;i<c4.length;i++){
     sb.append(c4);            
}
System.out.println(c4);

输出效果:adsads

方法三:new String(char[] c1); 分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。(推荐使用)

char[] c4 = new char[]{'a','d','s','a','d','s'};
return new String(c4);

输出效果:adsads

Sort

import java.util.Scanner;

//父类
class ParentSort
{
	public void sort(int[] array)
	{
		System.out.println("排序算法");
	}
	public void showArray(int[] array)
	{
		for(int i:array)
		{
			System.out.print(i+" ");
		}
	}
}

//选择排序类
class SelectSort extends ParentSort
{
	@Override
	public void sort(int[] array)
	{
		int index;
		for(int i=1;i<array.length;i++)
		{
			index = 0;
			for(int j=1;j<=array.length-i;j++)
			{
				if(array[j]>array[index])
				{
					index=j;
				}
			}
			int temp = array[array.length-i];
			array[array.length-i] = array[index];
			array[index] = temp;
		}
		System.out.print("选择排序:");
		showArray(array);
	}
}

//插入排序类
class InsertSort extends ParentSort
{
	@Override
	public void sort(int[] array)
	{
		for(int i=0;i<array.length;i++) 
		{
			 int j = i - 1;
			 int temp = array[i];   //记录要插入的数据  
			 while(j>=0 && array[j]>temp)  //从后向前,找到比其小的数的位置 
			 {
				 array[j+1] = array[j]; //向后挪动  
				 j--;
			 }
			 if(j != i-1) //存在比其小的数 
			 {
				 array[j+1] = temp;
			 }
		}
		System.out.print("插入排序:");
		showArray(array);
	}
}

//快速排序类
class FastSort extends ParentSort
{
	@Override
	public void sort(int[] array)
	{
		int left = 0;
		int right = array.length-1;
		sort(array,left,right);
		System.out.print("快速排序:");
		showArray(array);
	}
	
	public void sort(int[] array,int left1,int right1)
	{
		int left = left1;
        int right = right1;
        int temp = 0;
        if(left <= right) //待排序的元素至少有两个的情况
        {  
            temp = array[left];  //待排序的第一个元素作为基准元素
            while(left != right)//从左右两边交替扫描,直到left = right
            {   
                while(right > left && array[right] >= temp)  
                     right --;        //从右往左扫描,找到第一个比基准元素小的元素
                  array[left] = array[right];  //找到这种元素array[right]后与array[left]交换

                while(left < right && array[left] <= temp)
                     left ++;         //从左往右扫描,找到第一个比基准元素大的元素
                  array[right] = array[left];  //找到这种元素array[left]后,与array[right]交换

            }
            array[right] = temp;    //基准元素归位
            
            sort(array,left1,left-1);  //对基准元素左边的元素进行递归排序
            sort(array,left+1,right1);  //对基准元素右边的进行递归排序
        }
	}
}

//策略类
class Factory
{
	private ParentSort sort;
	//依赖注入 
	public void setSort(ParentSort sort)
	{
		this.sort = sort;
	}
	public void doSort(int[] array)
	{
		sort.sort(array);
	}
}

//测试类
public class SortTest
{
	public static void main(String[] args) 
	{
		int[] array = {63,4,24,1,3,15};
		Factory factory = new Factory();
		
		System.out.println("1、选择排序");
		System.out.println("2、插入排序");
		System.out.println("3、快速排序");
		
		System.out.print("请选择:");
		Scanner input = new Scanner(System.in);
		int number = input.nextInt();
		
		if(number == 1)
		{
			ParentSort selectSort = new SelectSort();
			factory.setSort(selectSort);
			factory.doSort(array);
		}
		
		if(number == 2)
		{
			ParentSort insertSort = new InsertSort();
			factory.setSort(insertSort);
			factory.doSort(array);
		}
		
		if(number == 3)
		{
			ParentSort fastSort = new FastSort();
			factory.setSort(fastSort);
			factory.doSort(array);
		}
	}
}

eclipse 删除所有注释及空白行

Ctrl+F 删除java注释:  /\*{1,2}[\s\S]*?\*/

Ctrl+F 删除xml注释:  <!-[\s\S]*?-->

Ctrl+F 删除空白行:   ^\s*\n

Ctrl+F 删除代码中的注释和空行:   /\*{1,2}[\s\S]*?\*/|\/\/.+|^\s*\n

勾选 Regular expressions 选择正则表达式  ,替换replaceAll全部即可。

数组的复制

1. for循环方法:
代码灵活,但效率低。

2. System.arraycopy()方法:
通过源码可以看到,其为native方法,即原生态方法。自然效率更高。
public static native void arraycopy(Object src, int srcPos,Object dest, int destPos,int length);

3. Arrays.copyOf()方法:
同样看源码,它的实现还是基于System.arraycopy(),所以效率自然低于System.arraycpoy()。

public static int[] copyOf(int[] original, int newLength) {
    	 int[] copy = new int[newLength];
    	 System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
         return copy;
}

4. Object.clone()方法:
从源码来看同样也是native方法,但返回为Object类型,所以赋值时将发生强转,所以效率不如之前两种。
protected native Object clone() throws CloneNotSupportedException;

For example

import java.util.Arrays;

/**
  * @author wrh
  */
 public class Test {
     public static void main(String[] args) {
         int[] array1 = {1,2,3,4,5};
        
         // 1.通过for循环
         int[] array2 = new int[5];
         for(int i = 0;i < array1.length;i++) {
             array2[i] = array1[i];
         }
         for(int i = 0;i < array2.length;i++) {
             System.out.print(array2[i]);
         }
         System.out.println();
         
         //2.通过System.arraycopy()
         int[] array3 = new int[5];
         System.arraycopy(array1, 0, array3, 0, 5);
         for (int i = 0; i < array3.length; i++) {
             System.out.print(array3[i]);
         }
         System.out.println();
         
         //3.通过Arrays.copyOf()
         int[] array4 = new int[5];
         array4 = Arrays.copyOf(array1, 5);
         for (int i = 0; i < array4.length; i++) {
             System.out.print(array4[i]);
         }
         System.out.println();
         
         //4.通过Object.clone()
         int[] array5 = new int[5];
			array5 = array4.clone();
         for (int i = 0; i < array5.length; i++) {
             System.out.print(array5[i]);
        }
	}
}

Overload和Override的区别

一、重写(override

override是重写(覆盖)了一个方法,以实现不同的功能。一般是用于子类在继承父类时,重写(重新实现)父类中的方法。

重写(覆盖)的规则:

  1. 重写方法的参数列表必须完全无与被重写的方法相同,否则不能称其为重写而是重载
  2. 重写方法的访问修饰符一定要大于被重写方法的访问修饰符
    (public>protected>default>private)
  3. 重写的方法的返回值必须和被重写的方法的返回一致;
  4. 重写的方法所抛出的异常必须和被重写方法的所抛出的异常一致,或者是其子类;
  5. 被重写的方法不能为private,否则在其子类中只是定义了一个方法,并没有对其进行重写。
  6. 静态方法不能被重写为非静态的方法(会编译出错)。

二、重载(overload
overload是重载,一般是用于在一个类内实现若干重载的方法,这些方法的名称相同而参数形式不同。

重载的规则:

  1. 在使用重载时只能通过相同的方法名、不同的参数形式实现。不同的参数类型可以是不同的参数类型,不同的参数个数,不同的参数顺序(参数类型必须不一样);
  2. 不能通过访问权限、返回类型、抛出的异常进行重载;
  3. 方法的异常类型和数目不会对重载造成影响;

java中Cookie的使用

1、cookie的来历

Cookie是WEB服务器通过浏览器保存在WWW用户端硬盘上的一个文本文件,这个文本文件中包含了文本信息。

文本信息的内容以“名/值”对(key/value)的形式进行存储。

可以让WEB开发者通过程序读写这个文本文件。

XP中保存Cookie的目录是“C://Documents and Settings/用户名/Cookies”

2、Cookie的作用

解决浏览器用户与Web服务器之间无状态通信。

3、什么是cookie

浏览器与WEB服务器之间是使用HTTP协议进行通信的,当某个用户发出页面请求时,WEB服务器只是简单的进行响应,然后就关闭与该用户的连接。因此当一个请求发送到WEB服务器时,无论其是否是第一次来访,服务器都会把它当作第一次来对待,这样的不好之处可想而知。为了弥补这个缺陷,Netscape开发出了cookie这个有效的工具来保存某个用户的识别信息,因此人们昵称为“小甜饼”。cookies是一种WEB服务器通过浏览器在访问者的硬盘上存储信息的手段:Netscape Navigator使用一个名为cookies.txt本地文件保存从所有站点接收的Cookie信息;而IE浏览器把Cookie信息保存在类似于C:\windows\cookies的目录下。当用户再次访问某个站点时,服务端将要求浏览器查找并返回先前发送的Cookie信息,来识别这个用户。

4、cookie的四个属性

  1. max-age:指定Ccookie的生存周期(以秒为单位)!默认情况下,Cookie的值只在浏览器的会话期间存在,当用户退出浏览器这些值就消失了!
  2. path:指定与Cookie关联在一起的网页.默认情况下,cookie会和创建它的网页以及与这个网页处于同一个目录下的网页和处于该目录下的子目录关联。
  3. domain:设置访问域 举个例子:位于order.example.com的服务器要读取catalog.example.com设置的cookie.这里就要引入domain属性,假定由位于catalog.example.com的页面创的cookie把自己的path属性设置为"/",把domain属性设置为".example.com",那么所有位于"catalog.example.com"的网页和所有位于"orders.example.com"的网页以及所有位于example.com域的其他服务器上得网页都能够访问这个cookie.如果没有设置cookiedomain值,该属性的默认值就是创建cookie的网页所在的 服务器的主机名。 注意:不能将一个cookie的域设置成服务器所在的域之外的域.
  4. seure:指定在网络上如何传输cookie的值

5、cookiesetPath方法

正常的cookie只能在一个应用**享,即一个cookie只能由创建它的应用获得。
1.可在同一应用服务器内共享方法:设置cookie.setPath("/");
本机tomcat/webapp下面有两个应用:webapp_a和webapp_b,

  1. 原来在webapp_a下面设置的cookie,在webapp_b下面获取不到,path默认是产生cookie的应用的路径。
  2. 若在webapp_a下面设置cookie的时候,增加一条cookie.setPath("/");或者cookie.setPath("/webapp_b/");就可以在webapp_b下面获取到cas设置的cookie了。
  3. 此处的参数,是相对于应用服务器存放应用的文件夹的根目录而言的(比如tomcat下面的webapp),因此cookie.setPath("/");之后,可以在webapp文件夹下的所有应用共享cookie,而cookie.setPath("/webapp_b/");. 是指cas应用设置的cookie只能在webapp_b应用下的获得,即便是产生这个cookie的webapp_a应用也不可以。
  4. 设置cookie.setPath("/webapp_b/jsp")或者cookie.setPath("/webapp_b/jsp/")的时候,只有在webapp_b/jsp下面可以获得cookie,在webapp_b下面但是在jsp文件夹外的都不能获得cookie
  5. 设置cookie.setPath("/webapp_b");,是指在webapp_b下面才可以使用cookie,这样就不可以在产生cookie的应用webapp_a下面获取cookie
  6. 有多条cookie.setPath("XXX");语句的时候,起作用的以最后一条为准。

6、cookie.setDomain方法设计跨越共享
A机所在的域:home.langchao.com,A有应用webapp_a
B机所在的域:jszx.com,B有应用webapp_b

  1. webapp_a下面设置cookie的时候,增加cookie.setDomain(".jszx.com");,这样在webapp_b下面就可以取到cookie
  2. 输入url访问webapp_b的时候,必须输入域名才能解析。比如说在A机器输入:http://lc-bsp.jszx.com:8080/webapp_b,可以获取webapp_a在客户端设置的cookie,而B机器访问本机的应用,输入:http://localhost:8080/webapp_b则不可以获得cookie
  3. 设置了cookie.setDomain(".jszx.com");,还可以在默认的home.langchao.com下面共享

7、cookie编程

//创建对象  
        Date date = new Date() ;  
        Cookie c = new Cookie("lastVisited",date.toString()) ;  
//设定有效时间  以s为单位  
        c.setMaxAge(60) ;  
//设置Cookie路径和域名  
        c.setPath("/") ;  
        c.setDomain(".zl.org") ;  //域名要以“.”开头  
//发送Cookie文件  
        response.addCookie(c) ;  
//读取Cookie  
        Cookie cookies[] = request.getCookies() ;  
        Cookie c1 = null ;  
        if(cookies != null){  
            for(int i=0;i<cookies.length;i++){  
               c1 = cookies[i] ;  
               out.println("cookie name : " + c1.getName() + "   ") ;  
               out.println("cookie value :" + c1.getValue() + "<br>");  
            }  
        }  
  //修改Cookie  
       Cookie cookies[] = request.getCookies() ;  
       Cookie c = null ;  
       for(int i=0;i<cookies.length;i++){  
           c = cookies[i] ;  
           if(c.getName().equals("lastVisited")){  
              c.setValue("2010-04-3-28") ;  
              c.setMaxAge(60*60*12) ;  
              response.addCookie(c) ;     //修改后,要更新到浏览器中       
           }  
       }  
   
//删除Cookie,(将Cookie的有效时间设为0)  
       Cookie cookies[] = request.getCookies() ;  
       Cookie c = null ;  
       for(int i=0;i<cookies.length;i++){  
           c = cookies[i] ;  
           if(c.getName().equals("lastVisited")){  
              c.setMaxAge(0);  
              response.addCookie(c) ;  
           }  
       }  

8、使用Cookied的注意事项

  1. Cookie的大小和数量是有限制的。
  2. Cookie在个人硬盘上所保存的文本信息是以明文格式进行保存的,没有任何的加密措施。
  3. 浏览器用户可以设定不使用Cookie

9、实例:Servlet中的Cookie编程

cookieInput.html页面中的参数提交到SetCookie.java中,由SetCookie.java保存在浏览器的Cookie中,在SerCookie.java中链接到GetCookie.java从而读取刚刚保存的Cookie

SetCookie.java :  
public void doPost(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
   
        response.setContentType("text/html;charset=utf-8");  
        PrintWriter out = response.getWriter();  
        String username = request.getParameter("username") ;  
        //保存Cookie  
        if(username !=""){  
            Cookie c1 = new Cookie("username",username) ;  
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd") ;  
            Cookie c2 = new Cookie("lastVisited",sdf.format(new java.util.Date())) ;  
            c1.setMaxAge(60*60*60*12*30) ;  
            c2.setMaxAge(60*60*60*12*30) ;  
            response.addCookie(c1) ;  
            response.addCookie(c2) ;  
            out.println("Cookie保存成功!");  
            out.println("<br><br>") ;  
            out.println("<a href=GetCookie02>读取Cookie</a>") ;  
        }else{  
            response.sendRedirect("../cookieInput.html") ;  
        }  
          
          
        out.flush();  
        out.close();  
    }  
GetCookie.java:  
public void doPost(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
   
        response.setContentType("text/html;charset=utf-8");  
        PrintWriter out = response.getWriter();  
        out.println("<!DOCTYPE HTML PUBLIC /"-//W3C//DTD HTML 4.01 Transitional//EN/">");  
        out.println("<HTML>");  
        out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");  
        out.println("  <BODY>");  
          
        //读取Cookie  
        Cookie cookies[] = request.getCookies() ;  
        Cookie c = null ;  
        if(cookies != null){  
            for(int i=0;i<cookies.length;i++){  
                c = cookies[i] ;  
                if(c.getName().equals("username")){  
                    out.println("用户名: "+c.getValue());  
                    out.println("<br>");  
                }  
                if(c.getName().equals("lastVisited")){  
                    out.println("上次登录的时间: "+c.getValue());  
                }  
            }  
        }else{  
            out.println("No cookie !");  
        }  
          
        out.println("  </BODY>");  
        out.println("</HTML>");  
        out.flush();  
        out.close();  
    }  

jsp

1、http://localhost:8080/jsp/
	http://HTTP协议
	localhost表示本地,如果访问其他主机的服务器,则替换为要访问主机的IP地址
	8080表示当前服务器的端口号
	/jsp表示要访问的项目(工程)的路径
	/表示要访问的页面的路径,当前为默认路径
2、http://localhost:8080/jsp/jsp/myNewJsp.jsp
	jsp/myNewJsp.jsp
		jsp表示自定义文件夹路径
		myNewJsp.jsp表示自定义jsp文件
3、jsp的九大内置对象
	注意:jsp页面中所有Java代码必须包裹在<%%>中
	一:out输出对象,将内容输出到页面上
	二:request表示一次请求
		1、相对路径
			request.getRequestDispatcher("jie.jsp").forward(request,response);
		2、绝对路径
			request.getRequestDispatcher("/jsp/request/jie.jsp").forward(request,response);
		表示请求转发,使请求转发到指定页面,该行为为服务器行为(一次请求)
		getRequestDispatcher("requestJie.jsp")指定要去的页面,参数为String类型的路径
		forward(request,response)表示将当前请求中所含的信息一起转发
		特点:浏览器地址栏内容不变
	三:response表示重定向,响应对象
		1、相对路径
			response.sendRedirect("jie.jsp");
		2、绝对路径
			response.sendRedirect(request.getContextPath()+"/jsp/jieChuan/jie.jsp");
			request.getContextPath()表示获取当前项目在服务器上的路径
		表示重定向,使请求重新定向到新的请求或页面,还行为为浏览器行为(两次请求)
		sendRedirect("jie.jsp")表示设置重定向路径
		特点:浏览器地址栏内容改变(页面真实路径)
		http://localhost:8080/jsp/jsp/request/jie.jsp
	***注意:使用重定向跳转页面(请求)时,request不能传递值
	四:session表示浏览器级别作用域,会话对象
		作用:存储键值对,方便后续取用
		范围:浏览器级别,只要浏览器不关闭,当前session一直有效
	五:application表示服务器级别的作用域,上下文
		作用:存储键值对,方便后续取用
		范围:服务器级别,只要服务器不关闭,当前application一直有效
	最后四个:page		pageContext		config		exception
	
4、四大作用域
	page	request		session		application


5、Java代码和HTML代码结合使用
	可以将Java代码前后分离,只要所有<%%>连接起来,Java代码整齐就行,在%>HTML代码<%中间书写HTML代码
	如果需要对Java变量进行输出,则需要将Java变量使用<%=变量%>包裹
6、el表达式
	写法:${键}
	作用:接收三大作用域中传递的值
	顺序:当三大作用域同时传递同样的键时,request>session>application


7、HTML表单(form)提交方式
	get:显式提交	有body部分,所有参数名称和参数值(参数名称=参数值)显示在浏览器地址栏中
	post:隐式提交	没有body部分,表单元素组成的参数名称和参数值不显示在浏览器地址栏中
	注意***:表单元素组成的参数名称和参数值:表单元素的name属性值作为参数名称,value属性值做参数值
8、中文乱码		
	隐式提交:使用request.setCharacterEncoding("utf-8");可解决
	注意:以上方式中,转码方法必须放在第一行
	显式提交:new String(hua.getBytes("utf-8"),"iso8859-1");终极转码方式

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.