Posted in Java, 技术

图解 Java IO : 二、FilenameFilter源码

Writer      :BYSocket(泥沙砖瓦浆木匠)

微         博:BYSocket

豆         瓣:BYSocket

FaceBook:BYSocket

Twitter    :BYSocket

从上一篇 图解 Java IO : 一、File源码 并没有把所有File的东西讲完。这次讲讲FilenameFilter,关于过滤器文件《Think In Java》中写道:

更具体地说,这是一个策略模式的例子,因为list()实现了基本功能,而按着形式提供了这个策略,完善list()提供服务所需的算法。

java.io.FilenameFilter是文件名过滤器接口,即过滤出符合规则的文件名组。

一、FilenameFilter源码

image

从IO的UML可以看出,FilenameFilter接口独立,而且没有它的实现类。下面就看看它的源码:

public interface FilenameFilter {
    /**
     * 测试指定文件是否应该包含在某一文件列表中。
     *
     * @param   被找到的文件所在的目录。
     * @param   文件的名称
     */
    boolean accept(File dir, String name);
}

从JDK1.0就存在了,功能也很简单:就是为了过滤文件名。只要在accept()方法中传入相应的目录和文件名即可。

深度分析:接口要有真正的实现才能算行为模式中真正实现。所以这里使用的是策略模式,涉及到三个角色:

环境(Context)角色

抽象策略(Strategy)角色

具体策略(Context Strategy)角色

结构图如下:

filenameFilter

其中,FilenameFiler Interface 就是这里的抽象策略角色。其实也可以用抽象类实现。

但是,装饰器模式也有缺点:在编写程序的时候,它提供了相当多的灵活性(容易混合和匹配属性),同时也增加了代码的复杂性

 

 

 

二、使用方法

image

如图 FilenameFiler使用如图所示。上代码吧:(small 广告是要的,代码都在 开源项目java-core-learning。地址https://github.com/JeffLi1993

package org.javacore.io;

import java.io.File;
import java.io.FilenameFilter;
/*
 * Copyright [2015] [Jeff Lee]
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @author Jeff Lee
 * @since 2015-7-20 13:31:41
 * 类名过滤器的使用
 */
public class FilenameFilterT {

	public static void main(String[] args) {
		// IO包路径
		String dir = "src" + File.separator +
				"org" + File.separator +
				"javacore" + File.separator +
				"io";
		File file = new File(dir);
		// 创建过滤器文件
		MyFilter filter = new MyFilter("y.java");
		// 过滤
		String files[] = file.list(filter);
		
		// 打印
		for (String name : files) {
			System.err.println(name);
		}
	}
	
	/**
	 *	内部类实现过滤器文件接口
	 */
	static class MyFilter implements FilenameFilter {
		
		private String type;
		
		public MyFilter (String type) {
			this.type = type;
		}

		@Override
		public boolean accept(File dir, String name) {
			return name.endsWith(type);// 以Type结尾
		}
		
	}
}

其中我们用内部类的实现,实现了FilenameFilter Interface。所以当我们File list调用接口方法时,传入MyFilter可以让文件名规则按我们想要的获得。

右键 Run 下,可以看到如图所示的输出:

image

 

补充:

String[] fs = f.list()

File[] fs = f.listFiles()

String []fs = f.list(FilenameFilter filter);;

File[]fs = f.listFiles(FilenameFilter filter);

image


三、总结

1、看源码很简单,看怎么用先,在深入看有什么数据结构,设计模式。理理就清楚了

2、学东西,学一点一点深一点。太深不好,一点就够了

3、泥瓦匠学习的代码都在github上(同步osc git),欢迎大家点star,提意见,一起进步。地址:https://github.com/JeffLi1993

Writer      :BYSocket(泥沙砖瓦浆木匠)

微         博:BYSocket

豆         瓣:BYSocket

FaceBook:BYSocket

Twitter    :BYSocket

Posted in Java, 技术

Servlet & JSP : 一、小姐,来桶全家桶不?(Servlet)

Writer      :BYSocket(泥沙砖瓦浆木匠)

微         博:BYSocket

豆         瓣:BYSocket

FaceBook:BYSocket

Twitter    :BYSocket

一.前言

  小生不才,大二下半学期第二个星期,近11月博客园。星期六闲来看看经典书。重温下Serlvet


二.温故而知新:超文本转移协议HTTP

HTTP协议是通过互联网(internet)或企业内部网(intranet)交换数据。介绍下http请求,http响应的过程。

#KFC点全家桶 – HTTP实现的是资源的请求和传送,类似点单。

1)请求(request):小姐向服务员post请求:“来个全家桶”。(postget是最常用的,下文HttpServlet中会涉及.)

2)回复(response):服务员根据情况,回应顾客的请求。

#多发情况-服务员的响应

1)服务员准备全家桶,交给小姐。(返回 200 成功状态码)

2)服务员今天不销售全家桶,反馈无。(无法找到某资源404

3)服务员将命令转给准备的厨师。(重定向redirect


三.Servlet  API (自顶向下模式讲解)

展示下javax.servlet.http中主要的类型:

                           KFC组织图(Serlvet 重要成员)

javax.servlet.Servlet,先搞个kfc机构出来–引例#MyServlet类

package sedion.jeffli.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;

@WebServlet(name = "MyServlet"  , urlPatterns = {"/my"})
public class MyServlet implements Servlet{

    private transient ServletConfig servletConfig;
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
        
    }

    @Override
    public ServletConfig getServletConfig() {
        // TODO Auto-generated method stub
        return servletConfig;
    }

    @Override
    public String getServletInfo() {
        // TODO Auto-generated method stub
        return "M 0333333333y Servlet";
    }

    @Override
    public void init(ServletConfig arg0) throws ServletException {
        // TODO Auto-generated method stub
        this.servletConfig = arg0;
    }

    @Override
    public void service(ServletRequest arg0, ServletResponse arg1)
            throws ServletException, IOException {
        String servletName = servletConfig.getServletName();
        arg1.setContentType("text/html");
        PrintWriter writer = arg1.getWriter();
        writer.print("<html><head></head><body>Helo:"+servletName+"</body></html>");
        
    }

}

然后web工程部署,tomcat 7 注意要7以上。然后火狐敲入:http://localhost:8080/web工程名/my

解剖源码(小生温州医科大学,恶心一下提提神)

@WebServlet(name = “MyServlet” , urlPatterns = {“/my”})

WebServlet注解类型来声明一个Servlet。在声明同时,还可以告诉容器那个URL调用这个Serlvet。name是可选的,urlPattern也是可选的,但几乎都会用到它。urlPattern告诉容器,/my模式可以调用这个MyServlet。(一个通道,方便购买全家桶,小姐你要吗?),自然用web.xml部署描述也是可以的。

MyServlet类,重写了Servlet类中的init→service→destroy方法,属于Servlet生命周期方法。

其中service方法,会根据请求的方法,进行调用下面的方法。

 

#ServletRequest

getParameter最常用的方法。通常用来返回一个html表单域的值。也可以用来获取查询字符串的值。例,利用URL调用:http://localhost:8080/servletTest/my?id=jeffliId 

就可以用下面语句来获取id的值:String id = request.getParameter(“id”);


#ServletResponse

在调用service方法之前,Servlet容器会创建一个ServletResponse。其中定义的getWriter()方法,返回可将文本床给客户端java.io.PrintWriter。默认PrintWriter对象采用ISO-8859-1编码。

#ServletConfig
@WebServlet中以下面这种方式初始化值,值由:键和值。

@WebServlet(
        name = "MyServlet"  ,
        urlPatterns = {"/my"},
        initParams = {
            @WebInitParam(name="jeffliName",value="QiangqiangLi")
        }
    )

#ServletContext
每个web应用只有一个context,在分布式环境下,一个应用可以同时分布到多个容器,并且每个java虚拟机都有一个ServletCotext对象。 
    
javax.servlet.GenericServlet

这个抽象类给我们完成了Servlet接口中所有方法提供默认实现等,方便了我们用。如果MyServlet类继承GenericServlet,我们只需要重写service方法即可。(小姐,你坐着不用走普通流程,我们给你绿色通道。全家桶马上来!)


Http Servlet

Http Servlet两种特性:

1)不覆盖service方法,而是覆盖doGet,doPost。极少情况下,覆盖doHead,doPut,doTrace,doOptions或doDelete。

2)用HttpServletRequest和HttpServletResponse 代替 ServletRequest 和ServletResponse。因为将请求相应对象分别从Servlet容器向下转换。


HttpServletRequest

HttpSession getSession() 返回session对象,没有的话,创建新的session对象。


四.Servlet完成一次请求处理的过程

从客户端(Guest)向服务器发送HTTP请求,该HTTP请求传递给Servlet Container。该Container负责:

分析HTTP请求的信息,并新建request对象,将HTTP请求中的信息放入request对象

    • 新建response对象
    • 根据web.xml(或注释生成),查找URL对应的Servlet对象。如果Servlet对象不存在,则新建相应Servlet对象。
    • 创建新的线程,用于处理本次请求。线程拥有指向request和response对象的引用。

五.参考文献[在此感谢]

http://book.douban.com/doulist/3575997/

http://www.cnblogs.com/vamei/archive/2013/05/12/3073932.html

泥瓦匠学习的代码都在github上(同步osc git),欢迎大家点star,提意见,一起进步。地址:https://github.com/JeffLi1993

Writer      :BYSocket(泥沙砖瓦浆木匠)

微         博:BYSocket

豆         瓣:BYSocket

FaceBook:BYSocket

Twitter    :BYSocket

Posted in Java, 技术

Servlet & JSP : web.xml 配置学习

Writer      :BYSocket(泥沙砖瓦浆木匠)

微         博:BYSocket

豆         瓣:BYSocket

FaceBook:BYSocket

Twitter    :BYSocket

一.定义

定义时注意:xml元素是区分大小写的,以下必须小写:

<web-app></web-app>

二.url-pattern

1)url-pattern 的值必须以/或者*.开头

  <servlet>
    <servlet-name>TestName</servlet-name>
    <servlet-class>sedion.jeffli.servlet.AServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>TestName</servlet-name>
    <url-pattern>/UrlTest1</url-pattern>
  </servlet-mapping>
<!--
  <servlet-mapping>
      <servlet-name>TestName</servlet-name>
      <url-pattern>*.urlTest1</url-pattern>
    </servlet-mapping>
-->

2)匹配模式的规则

①优先处理完全匹配

/test1/aa 和 /test1/* 都是一个url-pattern访问路径,则优先请求 http://localhost/webAppTest/test1/aa

②目录映射优先于扩展名映射

/test1/aa 和 /test1/*.html 都是合法的url-pattern访问路径,则优先请求 http://localhost/webAppTest/test1/aa/test.html

③对于重复映射,越长路径越优先

/test1/aa/* 和 /test1/* 都是一个url-pattern访问路径,则优先请求 http://localhost/webAppTest/test1/aa/test.html

三.过滤器

在web.xml文件中使用 filter元素和 filter-name(任意名),filer-class(完全限定类名)声明:

<filter>
  <filter-name>
    TestFilterName
  </filter-name>
  <filter-class>
    sedion.jeffli.testFilter
  </filter-class>
</filter>

通过filter-mapping与

①【servlet-name】一个元素或者多个servlet关联

<filter-mapping>
    <filter-name>TestFilterName</filter-name>
    <servlet-name>SomeServletName</servlet-name>
</fitler-mapping>

【url-pattern】jsp页面关联

<filter-mapping>
    <filter-name>TestFilterName</filter-name>
    <url-pattern>/*</url-pattern>
</fitler-mapping>

四、配置jsp页面

jsp-config 中有两个子元素【taglib】【jsp-property-group】,注意,前者必须出现在后者之前。

【taglib】替代jsp页面中taglib指令

<jsp-config>
    <taglib>
        <taglib-uri>/taglibtest</taglib-uri>
        <taglib-location>/WEB-INF/tlds/test-tags.tld</taglib-location>
    </taglib>
</jsp-config>

配置后,在页面可以用下面简单方式调用标签库

<% taglib uri="/taglibtest" prefix="somePrefix">

五、面向群集环境的开发

例如,tomcat自带一个软件负载器,存在Web应用的tomcat_dir/weapps/blalancer中。

开发一个应用于群集环境的Web应用注意以下几点:

①避免创建实例化变量和静态数据来共享数据。

②不要将数据存储在 ServletContext

③存储在HttpSession中的对象需要实现Serializable接口

如果HttpSession保存的对象不实现Serializable接口,容器便不能迁移会话。

④尽量少在HttpSession中存储信息

在HttpSession中存储大量数据,会降低Web应用性能,特别是请求量相当高时。

泥瓦匠学习的代码都在github上(同步osc git),欢迎大家点star,提意见,一起进步。地址:https://github.com/JeffLi1993

Writer      :BYSocket(泥沙砖瓦浆木匠)

微         博:BYSocket

豆         瓣:BYSocket

FaceBook:BYSocket

Twitter    :BYSocket

Posted in Java, 技术, 系列文章

[Java 容器 & 泛型] 系列文章

容器是Java语言学习中重要的一部分。

java-collection-hierarchy_thumb

文章如下:

  1. Java 容器 & 泛型:一、认识容器

  2. Java 容器 & 泛型:二、ArrayList 、LinkedList和Vector比较

  3. Java 容器 & 泛型:三、HashSet,TreeSet 和 LinkedHashSet比较

  4. Java 容器 & 泛型:四、Colletions.sort 和 Arrays.sort 的算法

  5. Java 容器 & 泛型:五、HashMap 和 TreeMap的自白

  6. Java 容器 & 泛型:六、容器讲到为什么要使用泛型

 

文章源码地址:https://github.com/JeffLi1993

Writer      :BYSocket(泥沙砖瓦浆木匠)

微         博:BYSocket

豆         瓣:BYSocket

FaceBook:BYSocket

Twitter    :BYSocket

Posted in Java, 技术

图解 Java IO : 一、File源码

Writer      :BYSocket(泥沙砖瓦浆木匠)

微         博:BYSocket

豆         瓣:BYSocket

FaceBook:BYSocket

Twitter    :BYSocket

记得Java源码是集合开始看的,写了一系列集合相关的文章,受到不错的评价。感谢各位读者。我依旧会读到老写到老,并生动形象的写出来心得体会。这次依旧是图解,我研究IO这块。

Java IO – File的要点,应该是

1、跨平台问题的解决

2、文件的安全

3、文件的检索方法

一、代码小引入

代请看一个简单的小demo:(ps:开源项目java-core-learning地址https://github.com/JeffLi1993

import java.io.File;
import java.util.Arrays;
/*
 * Copyright [2015] [Jeff Lee]
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @author Jeff Lee
 * @since 2015-7-13 07:58:56
 * 列出目录并排序
 */
public class DirListT {
	public static void main(String[] args) {
		// 获取当前目录
		File path = new File(".");// .表示当前目录
		// 文件路径名数组
		String list[] = path.list();
		
		// 对String文件名进行排序
		Arrays.sort(list,String.CASE_INSENSITIVE_ORDER);
		
		// 打印
		for(String dirItem : list)
			System.out.println(dirItem);
	}
}

在eclipse中,右键run一下,可以得到如下的结果:

image

如图,很容易注意到了,其目录下的名字排序按字母并打印了。

先回顾下API知识吧,

首先构造函数 public File(String pathname)

通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。如果给定字符串是空字符串,那么结果是空抽象路径名。

参数:
pathname – 路径名字符串
抛出:
NullPointerException – 如果 pathname 参数为 null
二者,File实现了Comparator接口,以便对FileName进行排序

static Comparator<String>
     CASE_INSENSITIVE_ORDER
          一个对 String 对象进行排序的 Comparator,作用与 compareToIgnoreCase 相同。

三者, path.list()为什么会返回String[] filenams的数组呢?怎么不是List呢?

自问自答:这时候,我们应该去看看ArrayList的实现,ArrayList其实是动态的数组实现。动态,动态的弊端就是效率低。此时,返回一个固定的数组,而不是一个灵活的类容器,因为其目录元素是固定的。下面是ArrayList和数组Array的比较

绘图1

 

二、深入理解源码

File,File究竟是怎么构成的。顺着源码,知道了File有几个重要属性

clipboard

1、static private FileSystem fs

     FileSystem : 对本地文件系统的抽象

2、String path 文件路径名

3、内联枚举类

     PathStatus 地址是否合法 ENUM类 private static enum PathStatus { INVALID, CHECKED };

4、prefixLength 前缀长度

如下,给出File相关核心的UML图
file

 

其实操作的是 FileSystem : 对本地文件系统的抽象,真正操作的是 FileSytem派生类。通过源码Ctrl+T发现如下:Win下操作的是 Win32FileSystemWinNTFileSystem类。看来真正通过jvm,native调用系统的File是他们。

clipboard[1]

Linux呢?因此,下了个Linux版本的JDK,解压,找到rt.jar。然后java/io目录中,找到了UnixFileSystem类。真相大白了!

clipboard[2]

 

所以可以小结File操作源码这样调用的:中间不同JDK,其实是不同的类调用本机native方法

绘图1

三、小demo再来一发

File 其实和我们在系统中看的的文件一样。就像我们右键,属性。可以看到很多File的信息。Java File也有。下面是一个文件的相关方法详情:

import java.io.File;
/*
 * Copyright [2015] [Jeff Lee]
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @author Jeff Lee
 * @since 2015-7-13 10:06:28
 * File方法详细使用
 */
public class FileMethodsT {
	
	private static void fileData(File f) {
		System.out.println(
			" 绝对路径:" + f.getAbsolutePath() +
			"\n 可读:" + f.canRead() +
			"\n 可写:" + f.canWrite() +
			"\n 文件名:" + f.getName() +
			"\n 上级目录:" + f.getParent() +
			"\n 相对地址:" + f.getPath() +
			"\n 长度:" + f.length() +
			"\n 最近修改时间:" + f.lastModified()
			);
		if(f.isFile())
			System.out.println(" 是一个文件");
		else if(f.isDirectory())
			System.out.println(" 是一个目录");
	}
	
	public static void main(String[] args) {
		// 获取src目录
		File file = new File("src");
		// file详细操作
		fileData(file);
	}
}

在eclipse中,右键run一下,可以得到如下的结果:大家应该都明白了吧。

image

文件如何过滤呢?

以后独立讲吧,过滤涉及Filter类。

四、总结

1、看源码很简单,看数据结构。看如何调用。或者是有些设计模式

2、学东西,学一点一点深一点。太深不好,一点就够了

3、泥瓦匠学习的代码都在github上(同步osc git),欢迎大家点star,提意见,一起进步。地址:https://github.com/JeffLi1993

Writer      :BYSocket(泥沙砖瓦浆木匠)

微         博:BYSocket

豆         瓣:BYSocket

FaceBook:BYSocket

Twitter    :BYSocket

Posted in 技术, 系列文章

[JavaEE 要懂的小事] 图解系列总结

sl_201208231039199370

泥瓦匠喜欢把精致的东西,越做越精致,我觉得这就是专注了。比如写吧,找机会写,找好东西写才是王道。写别人没写过的,兴许人家懂。也会“哦”在心中默念。

[JavaEE 要懂的小事] 提纲如下:

一、Http协议相关

二、乱码处理相关

待续

一、Http协议相关

1. JavaEE 要懂的小事:一、图解Http协议

2. JavaEE 要懂的小事:二、图解 Cookie(小甜饼)

3. JavaEE 要懂的小事:三、图解Session(会话)

待续

Writer      :BYSocket(泥沙砖瓦浆木匠)

微         博:BYSocket

豆         瓣:BYSocket

FaceBook:BYSocket

Twitter    :BYSocket

Posted in 技术, 网络

JavaEE 要懂的小事:三、图解Session(会话)

Writer      :BYSocket(泥沙砖瓦浆木匠)

微         博:BYSocket

豆         瓣:BYSocket

FaceBook:BYSocket

Twitter    :BYSocket

相继 图解Http协议图解Cookie 之后,中间迷茫期哈,没写了!可是又要告诉你自己明明喜欢写为啥不写了!那就写吧,学到老学到老~ 然后写到老!本系列皆以图为主,力求简单易懂,娓娓道来`

 

一、Session由来

HTTP的无状态,也就是说,每次请求都是独立的线程。举个例子吧:购物中,你选择了A商品,加入购物车,这就是A线程。然后在选择B商品就是B线程。可是每次线程独立(对容器而言,A、B成了不同的用户),线程A不知道有B,B也不知道A。如何一起付款呢?

简答来说:怎么保存同个用户多个请求会话状态呢?自然HTTPS保证连接是安全的,可以使它与一个会话关联。

问题就在于如何跟踪同一个用户,选择自然很多:

1、EJB(有状态会话bean保存会话状态) 环境苛刻需要带EJB的J2EE服务器,而不是Tomcat这种Web容器。

2、数据库(这貌似万能的。针对数据)

3、就是我们要讲的HttpSession保存跨一个特定用户多个请求的会话状态

4、上面说的HTTPS,条件太苛刻了。

如图:session

 

二、Session机制

机制,什么用词有点高大上。其实就是把它内在的一点东西说出来。主要两个W:What?How?

What is Session?

Session代表着服务器客户端一次会话的过程。直到session失效(服务端关闭),或者客户端关闭时结束。

How does session works?

Session 是存储服务端的,并针对每个客户端(客户),通过SessionID来区别不同用户的。Session是以Cookie技术或URL重写实现。默认以Cookie技术实现,服务端会给这次会话创造一个JSESSIONID的Cookie值。

 

补充

其实还有一种技术:表单隐藏字段。它也可以实现session机制。这里只是作为补充,服务器响应前,会修改form表单,添加一个sessionID类似的隐藏域,以便传回服务端的时候可以标示出此会话。

这技术,也可以使用在Web安全上,可以有效地控制CSRF跨站请求伪造

三、详细介绍Session机制过程

绘图3

 

 

图中这是session第一次请求的详细图。以Cookie技术实现,我也写了个HttpSessionByCookieServletT.java 的Servlet小demo,模拟下Session的一生。代码如下:

package org.servlet.sessionMngmt;

import java.io.IOException;
import java.io.PrintWriter;

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 javax.servlet.http.HttpSession;
/*
 * Copyright [2015] [Jeff Lee]
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @author Jeff Lee
 * @since 2015-7-12 10:58:28
 * 	HttpSession的默认Cookie实现案例
 */
@WebServlet(urlPatterns = "/sessionByCookie")
public class HttpSessionByCookieServletT extends HttpServlet {

	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
			throws ServletException, IOException {
		
		// 获取session
		// 如果是第一次请求的话,会创建一个HttpSession,等同于 req.getSession(true);
		// 如果已存在session,则会获取session。
		HttpSession session = req.getSession();
		
		if (session.isNew()) {
			// 设置session属性值	
			session.setAttribute("name", "Jeff");
		}
		// 获取SessionId
		String sessionId = session.getId();
		
		PrintWriter out = resp.getWriter();
		// 如果HttpSession是新建的话
		if (session.isNew()) {
			out.println("Hello,HttpSession! <br>The first response - SessionId=" 
					+ sessionId + " <br>");
		} else {
			out.println("Hello,HttpSession! <br>The second response - SessionId=" 
					+ sessionId + " <br>");
			// 从Session获取属性值
			out.println("The second-response - name: " 
					+ session.getAttribute("name"));
		}
		
	}
	
}

隆重打个小广告:

泥瓦匠学习的代码都在github上(同步osc git),欢迎大家点star,提意见,一起进步。地址:https://github.com/JeffLi1993

① 客户端向服务端发送第一次请求

此时,客户端想让服务端把自己的名字设置到会话中。

② 服务端的容器产生该用户唯一sessionID的session对象,并设置值

可以从代码中看出通过从请求中req.getSession(),新生成了一个session对象。并设置了setAttribute(“name”, “Jeff”),key为string,value是对象皆可。

这时候,我们不用再把session通过cookie技术处理,容器帮我们处理了。

③ 容器响应 Set-Cookie:JSESSIONID= …

我们可以F12,查看此次响应。

image

 

从图中可得到,每个Cookie的set,都有一个对应Set-Cookie的头。HttpOnly可是此Cookie只读模式。只不过session唯一标识是:JSESSIONID

浏览器解析Cookie,保存至浏览器文件。

image

如图,找到了对应的session存储的cookie文件。该文件被保护不能打开。图解Cookie 教你怎么找到该文件。

 

第二次请求会发什么变化呢?

session2

下面,泥瓦匠重新访问了这个地址:

① 再次请求

image

此时,请求会有Cookie值:JSESSIONID=… 该值传给服务端

② 容器获取SessionId
,关联HttpSession

③ 此时响应无SetCookie

如图:

image

但是这次请求,我们响应出上一次请求set的值。Jeff 就打印出来了!

 

关于服务端获取session,也就是从请求中获取session对象,容器会帮你根据Cookie找到唯一的session对象。

泥瓦匠记忆小抄:Session机制,记住两次请求图即可。

 

 

四、补充

点到为止哈~ 以后详细写。此图来自网络

wkiom1l4oh2s5jwhaaa5g2i22fe912

上图Bad guy,就是攻击者。跨站请求伪造,伪造用户请求来对服务器数据或者是用户等造成威胁。web安全也就是从这些基础中慢慢提升。

 

五、总结

1、大概地描述了session的工作机制,和一些安全相关。记住Session是什么,怎么用,在服务端客户端之间怎么传输即可。

2、泥瓦匠学习的代码都在github上(同步osc git),欢迎大家点star,提意见,一起进步。地址:https://github.com/JeffLi1993

Writer      :BYSocket(泥沙砖瓦浆木匠)

微         博:BYSocket

豆         瓣:BYSocket

FaceBook:BYSocket

Twitter    :BYSocket

 

Posted in Working Skills, 技术

Mybatis 3 配置 Log4j,打印SQL

Writer      :BYSocket(泥沙砖瓦浆木匠)

微         博:BYSocket

豆         瓣:BYSocket

FaceBook:BYSocket

Twitter    :BYSocket

MyBatis Logging可以对包、类、命名空间做语句记录。Log4J为例。配置日志功能非常简单:

步骤1:添加Log4J的jar

无论你是web还是企业应用,将jar添加lib下。或者是对日志系统独立应用,将jar添加到-calsspath下。

步骤2:配置Log4J

配置及其简单,在log4j.properties文件下:

# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

log4j把日志分为ALL、TRACE&(跟踪)、DEBUG(调试)、INFO(信息)、WARNING(警告)、ERROR(错误)、FITAL(致命)、OFF等几个级别,级别依次升高。级别高的Level会屏蔽级别低的信息。

ConversionPattern设置输出格式的参数说明:

 %p: 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL,

 %d: 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2011年08月30日 15:00:00,921

%r: 输出自应用启动到输出该log信息耗费的毫秒数

%c: 输出日志信息所属的类目,通常就是所在类的全名

%t: 输出产生该日志事件的线程名

%l: 输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)

%x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。

%%: 输出一个”%”字符 %F: 输出日志消息产生时所在的文件名称 %L: 输出代码中的行号 %m: 输出代码中指定的消息,产生的日志具体信息

%n: 输出一个回车换行符,Windows平台为”\r\n”,Unix平台为”\n”输出日志信息换行

可以在%与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式。如:

 1)%20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,默认的情况下右对齐。

 2)%-20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,”-”号指定左对齐。

 3)%.30c:指定输出category的名称,最大的宽度是30,如果category的名称大于30的话,就会将左边多出的字符截掉,但小于30的话也不会有空格。

 4)%20.30c:如果category的名称小于20就补空格,并且右对齐,如果其名称长于30字符,就从左边交远销出的字符截掉。