java web的基础技术与总结 jsp的基础知识 jsp的基础语法

jsp文件的头部标识代码是:

<%@ page language=“java” contentType=“text/html; charset=utf-8”
pageEncoding=“utf-8”%>

jsp的标签

<%! %> 定义变量和方法的标签,但是不能够在这里边执行jsp的程序
<% %> 程序代码的执行标签
<%= %> 这个是调用变量和方法的标签。
如下代码:
<%!
String name=“张三,你来呀”;
String getName(){
return “我就是张三的返回值”;
}
%>



<% out.println(this.name); %>


<%=
this.getName()//这个结尾是不能够有分号的,这标签表示的是直接输出的意思
%>

定义变量和方法在<%! %>和<%%>的区别

<%! %>代码块里边的内容如果没有变化,只会第一次刷新时会被执行。需要注意的是,每次调用这个值都是上一次保存在浏览器里边的值。
但是 <% %>代码块只要刷新就会执行,不管内容是否改变都会被执行。

导入包

<%@page import=“java.util.,java.text.” %>
如下实例,网页显示时间:
<%!
public String getNowTime(){
//日期格式化的类以及显示的格式
SimpleDateFormat formater=new SimpleDateFormat(“yyyy/MM/dd hh:mm:ss”);
//日期时间戳的获取
Date currentTime=new Date();
//将时间戳格式化并且返回
return formater.format(currentTime);
}
%>
<%=getNowTime() %>
**

jsp的内置对象

**
通过一个案例来说明jsp内置对象的一些方法。

人事系统登录的demo

用户类:###

package com.test.user;

//用户类的定义
public class Emp {
private String account;
private String name;
private String password;
private String email;

//创建一个用户的构造函数
public Emp(String account,String name,String password,String email) {
	this.account=account;
	this.name=name;
	this.password=password;
	this.email=email;
}

//get and  set methods
public String getAccount() {
	return account;
}

public void setAccount(String account) {
	this.account = account;
}

public String getName() {
	return name;
}

public void setName(String name) {
	this.name = name;
}

public String getPassword() {
	return password;
}

public void setPassword(String password) {
	this.password = password;
}

public String getEmail() {
	return email;
}

public void setEmail(String email) {
	this.email = email;
}

}
db类,数据类:###
package com.test.db;

import java.util.HashMap;
import java.util.Map;

import com.test.user.Emp;

/*

  • 正常来说这应该是一个操作数据库的包。但是目前我们用它来人为的制作数据

  • */
    public class DBUtil {
    //静态的成员变量
    public static Map<String,Emp> map=new HashMap<String,Emp>();

    //创造数据
    static {
    map.put(“101”,new Emp(“101”,“AA”,“123456”,“AA@qq.com”));
    map.put(“102”,new Emp(“101”,“BB”,“123456”,“BB@qq.com”));
    map.put(“103”,new Emp(“101”,“CC”,“123456”,“CC@qq.com”));
    map.put(“104”,new Emp(“101”,“DD”,“123456”,“DD@qq.com”));

    }

    //判断用户名和密码是否正确的方法
    //判断的是用户的账号和密码,所以用户是参数进来的
    public static boolean selectEmpByAccountPassword(Emp emp) {
    Boolean flag=false;
    for(String key:map.keySet()) {
    Emp e=map.get(key);
    if(e.getAccount().equals(emp.getAccount())
    && e.getPassword().equals(emp.getPassword())) {
    flag=true;
    break;
    }
    }
    return flag;

    }

}

登录的jsp页面

<h3>人事管系统的登录界面</h3>
<div class="form-module">
	<form action="control.jsp">
		<p>用户名:<input type="text" name="account" /></p>
		<p>密码:<input type="password" name="password" /></p> 
		<p><input type="submit" value="登录"/></p>
	</form>
</div>

处理登录的jsp页面

使用了jsp的内置函数request
<%
/request内置函数获取用户提交的信息以及http协议的信息,
request.getParameter获取提交参数
/

	String account=request.getParameter("account");
	String password=request.getParameter("password");
	
	/*
	如果jsp想使用java程序,那么使用import导入进来直接使用即可。
	*/
	//用户信息
	Emp emp=new Emp(account,null,password,null);
	//将用户信息进行验证
	Boolean flag=DBUtil.selectEmpByAccountPassword(emp);
	if(flag){//验证通过,表示登录成功
		out.println("登录成功");
	}else{//验证失败,表示登录失败
		out.println("登录失败");
	}
%>

登录成功后jsp页面的显示

如下代码,是html与java表达式的混合使用。

人事管理系统界面显示











<%
//使用for循环来遍历人事管理系统的信息
for(String key:DBUtil.map.keySet()){
%>






<%
}
%>
账号信息用户名密码邮箱
<% out.println(DBUtil.map.get(key).getAccount()); %><% out.println(DBUtil.map.get(key).getName()); %><% out.println(DBUtil.map.get(key).getPassword()); %><% out.println(DBUtil.map.get(key).getEmail()); %>

request内置函数的方法
request.setAttribute(“name”,“ren”);
request.getRequestDispatcher(“result.jsp”).forward(request,response);
request.getAttribute(“name”)

//给request设置属性,用于各个页面进行共同使用
request.setAttribute(“name”,“ren”);
//自动跳转到某页面,并且把request和reqsponse传递过去。并且路径还不会发生改变。
request.getRequestDispatcher(“result.jsp”).forward(request,response);

//获取值是:
<%= request.getAttribute("name") %>

pageContext内置对象的使用

pageContext.forward(“xxx.jsp?name=laohu”);
获取这个传递过来的参数值是:
request.getParameter(“name”);
包含其他页面的内置对象方法是:
pageContext.include(“xxx.jsp”);
pageContext还可以获取一些其他的对象:
pageContext.getRequest,pageContext.getSession…

session的使用

session.setAttribute(key,value);
session.getAttribute(key)
session和平时我们接触的session的使用方式是一样的,时间和关闭浏览器等方式可以让session失效。

配置login.jsp页面的xml

在web-info 文件夹下新建一个web.xml的文件。
文件里边的内容是:



login
/login.jsp


age
100

login /denglu.do

我再打开服务器发现运行login.jsp的地址的url是:http://localhost:8080/PersonnelExample/denglu.do
会发现页面的地址变成了/denglu.do了。

config的内置函数

通过上边的配置,config的内置函数有两个方法的使用如下:
config.getServletName()
config.getInitParameter(key)
config获取的servlet-name的值是:<%= config.getServletName() %>


config获取的初始化参数是:<%= config.getInitParameter(“age”) %>

exception内置函数的使用

在jsp页面中如果我们抛出了错误。如:
throw new exception(“xxx”);
我们可以在页面的头部设置一个专门处理错误页面的文件,使用的关键字是errorPage=“xxx.jsp”,如下:
<%@ page language=“java” contentType=“text/html; charset=utf-8”
pageEncoding=“utf-8” errorPage=“error.jsp”%>
所指定处理异常的页面,需要关键字来指定是处理异常的页面,关键字指定如下isErrorPage=“true”,如果不指定则不能够直接使用exception来捕获异常的错误信息,如下代码:
提示的错误是:<%= exception.getMessage() %>

application内置函数

这里我们会用一个网站访问次数的案例进行说明:
application的作用域。
//application的使用
Object count=application.getAttribute(“count”);
if(count==null){//说明是第一次访问该网站
application.setAttribute(“count”,1);
}else{
//把个数转变成整型
int i=(Integer)count;
//没访问一次就增加1
application.setAttribute(“count”,i+1);
}

url上传递的参数

jsp中get传递参数的方法:

修改

XML

有些过时了,所以不打算做笔记了。以后用到再说把。

servlet的使用

我们之前是使用jsp调用java的包来处理业务逻辑。但是这种方法不适合写接口,java本身程序无法直接进行连接的访问。而servlet就是来解决这个问题的。

第一个servlet程序

1,必须继承HttpServlet类。
2,重写两个方法。
如下代码:
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class servletTest1 extends HttpServlet{

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	// TODO Auto-generated method stub
	//get的请求访问
	System.out.println("doGet方法");
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	// TODO Auto-generated method stub
	//post的请求访问
	System.out.println("doPost方法");
}

}

配置web.xml

我们需要给这个java的应用程序配置一个能够访问url路径。而这个配置是在webContent下的web-info下新建一个web.xml文件。
一个servlet标签代表一个servlet类。
servlet-name是定义一个虚拟的servlet类在xml文件使用的名,和具体的路径对应。
servlet-class:就是具体的servlet类。
servlet-mapping:定义好的servlet的变量名所映射的url路径。
servlet-url:servelt-name所对应的具体的路径。
路径地址是:http://ip:端口/项目名/servelt-name的变量
如下代码的配置:


testServlet


com.test.serv.servletTest1

<servlet-mapping> 

	<servlet-name>
		testServlet
	</servlet-name>
	
	<url-pattern>
		/testServlet
	</url-pattern>
	
</servlet-mapping>

动态生成url

通过方法获取相关的url地址。
如下代码和注释:
out.println(request.getScheme()+",");//获取协议
out.println(request.getServerName()+",");//获取当前的ip
out.println(request.getServerPort()+",");//获取当前的端口
out.println(request.getServletContext().getContextPath());//获取项目名称
**

servlet的生命周期

**
生命周期主要是分3个周期:
第一个周期是init(只有在第一次请求时会被调用)。
第二个周期是service(只要是请求都会调用这个)。
第三个周期是desctory。
/**

  • Servlet implementation class ServletTest

  • 虚拟路径可以用如下的方式进行配置@WebServlet("/ServletTest")
    */
    @WebServlet("/ServletTest")
    public class ServletTest extends HttpServlet {

    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
    System.out.println(“每次只要请求这个页面就会被调用”);
    }

    @Override
    public void destroy() {
    /*
    * 只有阶段结束的时候才会被调用,并不是服务器关闭。
    * 而是整个项目在服务器上移除的时候会被调用
    * */
    System.out.println(“desctory被调用”);
    }

    @Override
    public void init() throws ServletException {
    /* 生命周期第一个周期是init
    * 只是第一次被打开的时候调用之后都不会被调用
    * */
    System.out.println(“init被调用”);
    }
    }

请求与响应

在servlet的类里边,请求与响应,分别是浏览器对服务器和服务器对浏览器。
如下:
HttpServletRequest request,
HttpServletResponse response

servletContext 和 serveletConfigz的使用

servletContext 表示的是该项目的运行文件。
servletConfig表示的是这个项目文件的配置文件,web.xml这个文件。

在一个java文件里边进行设置,如下代码表示:

//ServletContext表示的是当前的项目,那么在同一个项目下的不同的java文件下可以通过设置属性来进行数据共享
ServletContext context=this.getServletContext();
context.setAttribute("username","老胡");

在另一个java文件里边进行获取进行使用,只要是在同一个项目里边就可以:

//通过ServletContex来获取设置的属性数据
ServletContext context=this.getServletContext();
System.out.println("ServletContext:"+context);
Object username=context.getAttribute("username");
System.out.println("username"+username);

转发与重定向

转发与重定向的使用如下代码:
//生成随机数,如果随机数大于5则跳转成功页面,否则是失败的页面
Random r=new Random(1);
int i=(int)r.nextInt(10);
System.out.println(i);
if(i<6) {
//跳转到成功的页面,转发
request.getRequestDispatcher("/success.jsp").forward(request,response);

}else {
	//如果失败就是重定向页面,在设定路径的时候要加上项目名称,重定向
	response.sendRedirect("/serv/error.jsp");
}

转发并不会跳转到具体的页面,浏览器的地址还是原始的地址,虽然页面已经跳转了,如下图:在这里插入图片描述

重定向会跳转到具体的页面,浏览器的地址栏看的出。
在这里插入图片描述

转发与重定向参数的问题

转发的参数携带是使用request.setAttribute();进行设置的,获取是getAttribute()进行获取的。所以相对来说简单些。
具体说下,重定向参数的设置和获取,
如果说java文件之间的跳转:如下代码:
ServletContext context=request.getServletContext();
context.setAttribute(“username”,“huminggui”);
response.sendRedirect("/serv/ServletTest4");
如果是跳转到jsp页面,那么就是用application进行获取,如下:
//重定向参数的获取和设置
//携带参数用的是appliction或者是requestContext
ServletContext context=request.getServletContext();
context.setAttribute(“username”,“huminggui”);
response.sendRedirect("/serv/success.jsp");
jsp页面
<%
out.print(application.getAttribute(“username”));
%>

登录注册的案例

User类的创建:
User类的创建:
//这个是User类的关键字
private String username;
private String nickname;
private String password;
private String sex;
private String hobby;
private String path;

InitServlet
初始化用户数据表。
并且将这个用户数据表保存在ServletContext里边。
项目刚开始的时候就初始化上边的数据。是需要在web.xml里边进行配置的。
InitServlet的代码如下:
@Override
public void init() throws ServletException {
//创建数据集合
Listlist=new ArrayList();
ServletContext context=this.getServletContext();
//初始化数据
context.setAttribute(“list”,list);

}

在web.xml里边配置这个Servlet。
通过配置web.xml使项目在启动的时候就开始创建实例,web.xml的配置:

InitServlet
com.c.InitServlet

2

...省略其他

**

表单上传文件问题的解决

**
文件上传的条件是:

必须post方式
name属性必须有并且type=“file”
form表单的属性enctype的值必须是multipart/form-data

这个写错好几回:
enctype=“multipart/form-data”
需要用到2个jar的包。
在java中如果使用第三方的jar包,则需要把jar包放到web-info–>lib文件夹里边,然后再代码中就可以直接调用了。
两个jar包的使用导致了在接收form表达传递过来的数据无法用之前的request进行接收,具体的代码和注释如下显示:
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//创建一个磁盘文件工厂对象,用的是第三方的jar包
DiskFileItemFactory dfif=new DiskFileItemFactory();
//创建一个解析request的核心类,参数是磁盘文件工厂
ServletFileUpload slfu=new ServletFileUpload(dfif);
//解析request,返回request获取的表单的集合,FileItem是jar包给我们提供的类
List list =slfu.parseRequest(request);

		//遍历这个集合判断哪个是上传的文件,哪个是普通的表单元素
		for(FileItem fileItem:list) {
			
			if(fileItem.isFormField()) {
				String name=fileItem.getFieldName();//获取表单的name属性
				String value=fileItem.getString("utf-8");//获取表单的值
				System.out.println(name+":"+value);
			}
		}
	} catch (FileUploadException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
}

第三方的jar包分别是,如下代码和截图:
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

截图:
在这里插入图片描述

随机生成文件名的方法

public static String getFielUUIDName(String filename) {
//获取文件的后缀
int idx=filename.lastIndexOf(".");//获取最后一个点的位置
String ex=filename.substring(idx);//最后一个点开始截取的内容
//创建随机字符串,但是随机字符串中间会有-,去掉-,然后再把.jpg的内容连接
String randomFileName=UUID.randomUUID().toString().replace("-", “”)+ex;

	return randomFileName;
}

}

文件上传的实现

如下代码和注释:
//如果是文件则在这里进行处理
//获取提交上来的文件的文件输入流
String fname=fileItem.getName();
//获取文件输入流,就是上传文件的输入流
InputStream is=fileItem.getInputStream();

				//获取upload这个文件在项目的位置,getServletContext()是获取当前的项目名称
				String uploadPath=this.getServletContext().getRealPath("/upload"); 
				//获取.metadata之前的路径
				int start=uploadPath.indexOf(".metadata");
				String startPath=uploadPath.substring(0,start);
				//获取项目的名称
				String projectName=request.getContextPath().substring(1);
				//拼接图片上传的地址
				String url=startPath+projectName+"\\"+"upload";
				
				//文件的名称是通过其他工具类生成的
				String ex=FileUUIDName.getFielUUIDName(fname);
				//输出的路径是
				String outPath=url+"\\"+ex;
				
				//定义一个输出流
				OutputStream os=new FileOutputStream(outPath);
				//输出流写入文件
				int len=0;
				byte [] b=new byte[1024];
				while((len=is.read(b))!=-1) {
					os.write(b,0,len);
				}
				is.close();
				os.close();

用户名密码以及文件的校验

校验其实是在添加数据到数据文件的时候进行的一个验证。
如下是在Servletjava中进行的操作代码:
//把创建好的User实例存储到servletContext中
ServletContext context=this.getServletContext();
//在服务器刚启动时存储了list的集合,现在需要把这个集合进行更新
List userList=(List)context.getAttribute(“list”);
//校验用户名是否已经在数据集合里边了
for(User user:userList) {
if(user.getUsername().equals(map.get(“username”))) {
request.setAttribute(“msg”,“用户名已经存在了”);
request.getRequestDispatcher("/regist.jsp").forward(request, response);
return;
}
}

在regist.jsp中的代码是如下:
String msg="";
//是否有错误的信息
if(request.getAttribute(“msg”)!="" && request.getAttribute(“msg”)!=null){
msg=(String)request.getAttribute(“msg”);
}

用户名保存在cookie里边

首先通过提交上来的参数,判断是否需要将数据保存cookie。
cookie的使用,可以参考如下代码:
String remember=request.getParameter(“remember”);
//如果remember为true说明记住用户名的选项是勾住的
if(remember.equals(“true”)) {
Cookie cookie=new Cookie(“username”,user.getUsername());
//设置cookie保存的路径
cookie.setPath("/UserDmeo");
//设置cookie保存的时间以秒为单位
cookie.setMaxAge(606024);
//将cookie保存在response中
response.addCookie(cookie);
}
在jsp的页面中获取cookie的使用:
为了能够更
public class CookieUtils {
public static Cookie getCookie(Cookie [] cookies,String name) {
//传递进来的cookies数组不能够为null
if(cookies==null) {
return null;
}else {
//说明cookies是存在的,for循环cookies,来判断哪个是我们需要的cookie
for(Cookie cook :cookies) {
//如果cookie的键是一样的,说明是存在的
if(cook.getName().equals(name)) {
//返回这个cook
return cook;
}

		}
		return null;
	}
}

}

在jsp中使用cookie工具类并且进行赋值的操作如下:
//获取所有的cookie内容
Cookie[] cookies=request.getCookies();
//调用第三方的工具来寻找到自己需要的cookie
Cookie cookie=CookieUtils.getCookie(cookies,“username”);
if(cookie!=null){
uname=(String)cookie.getValue();
}

El表达式

保存在request作用域里边的变量可以直接通过el表示在另外一个页面上获取。
如下代码:
//把值保存在request的作用域上边
request.setAttribute(“username”,username);
request.setAttribute(“age”,age);

	//跳转到2.jsp中在这个页面用el的表达式获取这些数据
	request.getRequestDispatcher("/2.jsp").forward(request,response);

在跳转到的2.jsp的页面里边的代码是:
u s e r n a m e , {username}, username,{age}

jstl 和 el

入门与常用的标签
首先是需要一个jstl的一个jar包。
然后就是jsp页面上标签的几个固定的写法:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core"prefix=“c” %>

set out rmove的基本使用如下:

<!-- 之所以有这些标签是因为上边的prefix有指定这个标签,然后是scope的值可以是request、session等作用域。 -->
<c:set var="username" value="张三" scope="request"></c:set>
<c:out value="${username}"></c:out>
<hr>
<c:remove var="username" />
<c:out value="${username}"></c:out>

if标签和choose标签:
如下代码:

<c:if test="${username==张三}">
	我是张三
</c:if>

<!-- 类似if和else的的标签形式 -->

<c:choose>
	<c:when test="${age==13}">
		13岁
	</c:when>
	<c:otherwise>
		不是13岁
	</c:otherwise>
</c:choose>

jstl的forEach的使用:
我们这里会做一个小小的案例,就是在页面上显示一个数据的表格。
可以在另外一个页面使用这些数据,如下代码是产生数据的编码:
//创建一个map的数据,这个map里边的数据是一个产品的name、产地、价格
Map<String, Object> map=new HashMap<String, Object>();
//在这个map添加其他的数据
map.put(“name”,“联想电脑”);
map.put(“address”,“北京”);
map.put(“price”,4999);
//创建第二个对象
Map<String, Object> map2=new HashMap<String, Object>();
map2.put(“name”,“神州”);
map2.put(“address”,“南京”);
map2.put(“price”,3999);

	//把map这个对象放入打list里边
	List<Map<String,Object>> list=new ArrayList<Map<String, Object>>();
	list.add(map);
	list.add(map2);
	request.setAttribute("list",list);
	//数据添加到list里边后,页面跳转到5.jsp页面
	request.getRequestDispatcher("/5.jsp").forward(request,response);

登录的实例使用ajax

ajax的优点是局部刷新并不需要页面的提交就可以进行相关的操作。
jsp的登录页面的代码:

用户名:<input type="test" class="username" name="username"/>
<br>
密码:<input type="password" class="password" name="password" />
<br>
<p id="tip"></p>
<button id="sub">登录</button>

java代码是: json是需要另外的jar包支持的。
String username=request.getParameter(“username”);
String password=request.getParameter(“password”);
System.out.println(username+","+password);
JSONObject res;
//不管是验证通过还是失败都要给前端你返回一个结果
if(username.equals(“11”) && password.equals(“11”)) {
//表示的是验证通过
res=new JSONObject("{flag:true}");
}else {
//表示的验证失败
res=new JSONObject("{flag:false}");
}
//返回数据给前端,把json转成字符串然后转成byte格式。
response.getOutputStream().write(res.toString().getBytes(“utf-8”));

过滤器

定义过滤器和配置过滤器
代码:
public class CharFilter implements Filter {

@Override
public void destroy() {
	//过滤器销毁

}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
		throws IOException, ServletException {
	//根据xml的设置文件进行访问,只要满足条件就会执行这里边的操作。
	
	//表示调用下一个过滤器
	chain.doFilter(request,response);

}

@Override
public void init(FilterConfig arg0) throws ServletException {
	//过滤器就是刚开始项目启动的时候就会执行的,只启动一次

}

}

web.xml中配置过滤器:

charFilter
filters.CharFilter


charFilter
/*

获取过滤器在xml中的配置

在web.xml配置文件中是可以设置多个属性和值的,如下代码:
首先一定要定义的config是FilterConfig。
private FilterConfig config;
其次在filter初始化的时候,进行web.xml的获取,如下代码:
public void init(FilterConfig config) throws ServletException {
//过滤器就是刚开始项目启动的时候就会执行的,只启动一次
this.config=config;
}

最后是从获取到的配置对象里边获取响应的属性:
String ver=config.getInitParameter(“version”);

过滤器实现字符集编码问题

具体是用的是哪个编码,最好是设置在配置文件里边。
具体代码如下:
web.xml中的配置代码是:

charset
UTF-8

设置字符编码是:
//从配置文件获取编码标准
String charset=config.getInitParameter(“charset”);
request.setCharacterEncoding(charset);

登录安全的控制

但是下边的代码只是逻辑上是可以作为参考的,但是事实上可能并不是那么的成立。

    //获取session,查看session里边是否有username,如果存在则是表示登录,否则表示没有登录
	if(hrequest.getSession().getAttribute("username")==null) {
		//如果是null表示没有登录,这个时候返回到登录界面
		hresponse.sendRedirect(hrequest.getContextPath()+"/login.jsp");
		//hrequest.getRequestDispatcher("/login.jsp?flag=1").forward(hrequest,hresponse);
		return;
	}else {
		//表示已经登录那么就执行下一步操作即可
		//表示调用下一个过滤器
		chain.doFilter(hrequest,hresponse);
		return;
	}

过滤器的3种设置方式

就是过滤器在使用的时候针对forward的方式、include的方式,以及error错误页面的方式。4种方式都说在web.xml里边进行设置的。
默认是request方式。
forward
include
error
正常情况下如果不设置对forward的方式是不会被过滤的。
如下代码:
//如果设置为forward的模式,那么正常的url访问是不会触发过滤器的。
只有在request.getRequestDispatcher().forward();才会触发过滤器
//如果是include
则只有在
<jsp:include page="/test1.jsp" ></jsp:include>

//如果是错误的触发是,错误代码是404的时候或者是页面找不到的时候会触发过滤器。
则配置如下:

FilterDemo3 filter.TestFileter FilterDemo3 /test1.jsp ERROR 404 /test1.jsp

如果是response.sendError(404); 也会触发ERROR模式的filter。

多种模式的过滤器

如下代码就是多种模式的过滤器的web.xml的设置。

FilterDemo3 /test1.jsp ERROR Forward REQUEST

留言板案例

过滤器当访问这个页面时进行的过滤。
过滤器和node的中间件极度相似,也是一个过滤器完了后调用另外一个过滤器。

监听器

监听器入门
监听器主要是针对3个大的方面进行监听,一个context、sesssion、request。以及他们的attribute属性的监听的接口。
实现他们得监听器的接口,然后再web.xml里边进行注册。
第一个监听器的实例:
web服务器的开启和关闭时的监听器的代码:
public class TestListener implements ServletContextListener {

@Override
public void contextDestroyed(ServletContextEvent context) {
	System.out.println("ContextListener desctory...");

}

@Override
public void contextInitialized(ServletContextEvent context) {
	System.out.println("contextListener init ....");
	

}

}

在web.xml中的配置代码是:

com.listener.TestListener

多个监听器
如果是多个监听器在web.xml中进行配置。那么执行的顺序和配置的顺序是一样的。
监听器获取配置文件里边的参数
在配置文件里边设置web.xml:

app_name bigbig

Listener中的代码:
//获取配置文件中配置的属性
String appName=(String)context.getServletContext().getInitParameter(“app_name”);

session的监听器
当一个新的浏览器打开的时候,每次创建一个新的session。
public class httpSessionTest implements HttpSessionListener {

@Override
public void sessionCreated(HttpSessionEvent hse) {
	//创建的时候的id和时间
	String sessionId=hse.getSession().getId();
	Date createTime=new Date(hse.getSession().getCreationTime());
	System.out.println("sessionId:"+sessionId+","+"time:"+createTime);
}

@Override
public void sessionDestroyed(HttpSessionEvent hse) {
	//销毁的是哪个sessionId
	System.out.println("sessionId:"+hse.getSession().getId());
}

}

配置文件中session是可以设置时间的:

1

attribute的监听器
request 的代码是如下的:
public class TestRequestAttribute implements ServletRequestAttributeListener {

@Override
public void attributeAdded(ServletRequestAttributeEvent srae) {
	//添加属性的时候
	String name=srae.getName();
	String value=(String)srae.getValue();
	System.out.println("name:"+name+","+"value:"+value);
}

@Override
public void attributeRemoved(ServletRequestAttributeEvent arg0) {
	//删除属性的时候

}

@Override
public void attributeReplaced(ServletRequestAttributeEvent arg0) {
	//修改属性的时候

}

}
需要在刚问的文件里边进行如下的操作:
request.setAttribute(“username”,“laohu”);

java验证码

生成验证码的工具方法
这个是生成验证码的工具方法。
主要是注意两点:
1,图片验证码在流中,2,返回的code只是字符串。
如下代码:
public class CreateValidateCode {

//验证码的生成
/*
 * response 主要是用来输出图片的流
 * */
public static String createCodeImage(HttpServletResponse response) {
	//可以不把字符类型组件然后转变成字符串类型
	StringBuilder builder=new StringBuilder();
	
	for(int i=0;i<4;i++) {
		builder.append(randomChar());
	}
	String code=builder.toString();
	
	//设置图片的width和height
	int width=120;
	int height=25;
	
	//设定一个图片的缓存流,图片的高度和宽度,以及图片的背景。
	BufferedImage bi=new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
	//获取这个缓存流的绘制对象
	Graphics2D g=bi.createGraphics();
	//设置文字的大小和字体
	Font font=new Font("微软雅黑",Font.PLAIN,20);
	//颜色
	Color color=new Color(0,0,0);
	//设置字体
	g.setFont(font);
	//设置颜色
	g.setColor(color);
	//设置背景颜色
	g.setBackground(new Color(226,226,240));
	//开始绘制对象
	g.clearRect(0, 0, width, height);
	//获取这个绘制对象的上下文
	FontRenderContext context=g.getFontRenderContext();
	//获取绘制的矩形
	Rectangle2D bounds=font.getStringBounds(code,context);
	//计算坐标和间距
	double x=(width-bounds.getWidth())/2;
	double y=(height-bounds.getHeight())/2;
	double ascent=bounds.getY();
	double baseY=y-ascent;
	//绘画
	g.drawString(code, (int)x, (int)baseY);
	//结束绘制
	g.dispose();
	
	//最重要的一步是这个绘制好的图片输出的位置
	try {
		//把图片以jpg的格式写入到输出流里边
		ImageIO.write(bi,"jpg",response.getOutputStream());
		//刷新响应流
		response.flushBuffer();
	}catch (Exception e) {
		// TODO: handle exception
		e.printStackTrace();
	}
	
	
	
	
	
	return code;
}


private static char randomChar() {
	String coded="QWERTYUIOPLKJHGFDSAZXCVBNM1234567890";
	Random r=new Random();
	//只能在字符串的长度内才可以
	//在允许的随机生成的范围内才可以
	 return coded.charAt(r.nextInt(coded.length()));
}

}

jsp页面访问这个生成验证码图片的工具类,并且把输入流传递过去作为参数:
代码如下:
<%@ page language=“java” import=“util.*” contentType=“text/html; charset=UTF-8”
pageEncoding=“UTF-8”%>
<%
//首先要清楚浏览器的缓存,目的是为了情况浏览器的缓存,因为浏览器对网页是有记忆的,否则的话请求 会无法刷新。
response.setHeader(“pragma”,“no-cache”);
response.setHeader(“cache-control”,“no-cache”);
response.setHeader(“expires”,“0”);

//调用编写的生成验证码工具,把response的输出流给它,就会对接上输出流。
String code=CreateValidateCode.createCodeImage(response);
session.setAttribute("code",code);

//如何解决输出流getOutputStream异常问题。
out.clear();
out=pageContext.pushBody();

%>

前端jsp页面获取这个输入流并且进行图片的显示:
重点理论:img的src属性获取的是jsp的输出流的图片,所以图片会显示,如下代码:

看不清?点击刷新

算术验证码

其实就是算术的表达式写入到图片里边。
如下代码:
public static String computedCode(HttpServletResponse response) {

	//算术表达式
	Random r=new Random();
	int number1=(int)(Math.random()*10+1);
	int number2=(int)(Math.random()*10+1);
	//符号
	int isIChar=r.nextInt(3);
	
	String iChar="";
	int endNumber=0;
	switch(isIChar) {
		case 0:
			iChar="+";
			endNumber=number1+number2;
			break;
		case 1:
			iChar="-";
			endNumber=number1-number2;
			break;
		case 2:
			iChar="×";
			endNumber=number1*number2;
			break;
		default:
			
	}
	
	//需要写入到图片里边的字符串拼接起来
	String strValue=number1+" "+iChar+" "+number2+"=?";
	//System.out.println(strValue);
	//System.out.println(endNumber);
	
	//开始绘制图片
	//设置图片的width和height
	int width=120;
	int height=25;
	
	//设定一个图片的缓存流,图片的高度和宽度,以及图片的背景。
	BufferedImage bi=new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
	//获取这个缓存流的绘制对象
	Graphics2D g=bi.createGraphics();
	//设置文字的大小和字体
	Font font=new Font("微软雅黑",Font.PLAIN,20);
	//颜色
	Color color=new Color(0,0,0);
	//设置字体
	g.setFont(font);
	//设置颜色
	g.setColor(color);
	//设置背景颜色
	g.setBackground(new Color(226,226,240));
	//开始绘制对象
	g.clearRect(0, 0, width, height);
	//获取这个绘制对象的上下文
	FontRenderContext context=g.getFontRenderContext();
	//获取绘制的矩形
	Rectangle2D bounds=font.getStringBounds(strValue,context);
	//计算坐标和间距
	double x=(width-bounds.getWidth())/2;
	double y=(height-bounds.getHeight())/2;
	double ascent=bounds.getY();
	double baseY=y-ascent;
	//绘画
	g.drawString(strValue, (int)x, (int)baseY);
	//结束绘制
	g.dispose();
	
	//最重要的一步是这个绘制好的图片输出的位置
	try {
		//把图片以jpg的格式写入到输出流里边
		ImageIO.write(bi,"jpg",response.getOutputStream());
		//刷新响应流
		response.flushBuffer();
	}catch (Exception e) {
		// TODO: handle exception
		e.printStackTrace();
	}
	
	return strValue;
}

框架实现验证码
需要第三方jar包 : kaptcha-2.3.2.jar
框架实现验证码主要分成两部分:
一部分当然是jsp页面的访问。
另一部分是重点是:web.xml的配置。
配置如下:
jar包里边的包都是固定的,所以有些内容也是固定的。


Kaptcha
com.google.code.kaptcha.servlet.KaptchaServlet

<!-- 设置宽度和高度,这里是以这个为列,其实还有很多其他的属性是可以进行设置的 -->
<init-param>
     <param-name>kaptcha.image.width</param-name>
     <param-value>100</param-value>
</init-param>
<init-param>
   <param-name>kaptcha.image.height</param-name>
   <param-value>40</param-value>
</init-param>
 <init-param>
    <!--session.setAttribute("kcode",生成好的验证吗)-->
    <param-name>kaptcha.session.key</param-name>
    <param-value>kcode</param-value>
 </init-param>

</servlet>
Kaptcha /kaptcha.jpg

jsp中访问的页面是如下:

验证码的验证
验证码的验证比较重要。
验证码的验证过程是在servlet的类里边进行验证的,如下代码实现:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	//设置请求字符集
	request.setCharacterEncoding("utf-8");
	//设置响应字符集
	response.setCharacterEncoding("utf-8");
	//获取浏览器输入流的对象,用户向客户端输出内容
	PrintWriter out=response.getWriter();
	//获取传递过来的code
	String code=request.getParameter("code");
	System.out.println(code);
	//获取从session对象里边获取的code(第三工具提供的)这个是固定的写法,但是web.xml不能设置session标签了。
	//用常量比较好。如果web.xml有设置则直接写设置的key也可以。
	//但是最好不要用变量,因为web.xml改变则这里代码也得改变。
	String sessionCode
	=(String)request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
	System.out.println(sessionCode);
	if(sessionCode!=null && code!=null){
		//这个方法是不区分大小写的equalsIgnoreCase
		if(code.equalsIgnoreCase(sessionCode)) {
			out.print("success");
		}else {
			out.print("fail");
		}
	}else {
		out.print("fail");
	}
}

}

前端jsp页面的代码实现,如下:
这里有用到jq刷新验证码和用ajax提交页面请求:
$(function(){

	$("#code").click(function(){
		$(this).attr("src","http://localhost:8080/ValidateCodeDemo/kaptcha.jpg?"+new Date().getTime());
	});
	
	$("#btn").click(function(){
		$("#msg").html("");
		$.ajax({
			url:"http://localhost:8080/ValidateCodeDemo/loginServlet",
			type:"post",
			data:{
				code:$("#kcode").val()
			},
			success:function(res){
				if(res==="success"){
					alert("验证码输入成功");
				}else{
					$("#msg").html("验证码输入错误,请重新输入");
					$("#kcode").html("").focus();
				}
			}
		});
	});
});

intellij IDE的使用技巧

快捷键
ctrl+alt+s 设置页面
ctrl+shift+enter 自动补充方法或者其他结构
psvm 主方法
sout 是输出语句
fori for循环的快捷键
shift+f6(fn键按住) 是修改类的名字,会同时修改所有的使用这个类的名称,只限在当前文件下。属性也是同样的方法进行修改。
ctrl+alt+m 提取某一块为一个方法
alt +up/down 是一个一个方法的选中
shift+shift 查询
ctrl+h 当前类的继承关系的窗口
ctrl+f 当前页面的内容查询
两个设置的快捷键:ctrl+alt+s ctrl+shift+alt+s
文件和目录相关的
.iml 是工程的配置文件。out 是工程的输出语句
web项目的操作
创建时选择 web application
==在idea中的project可以创建多个module。一个module可以代表一个应用。
new–>module 就可以在当前项目下进行创建。

单点登录

暂时不想继续了,学起来费劲。
淘宝和天猫只要登录一端,另一端就自动登录了,这个就是单点登录。
单点登录的简称是sso。
主要的技术
Jsp Servlet HttpClient cookie Thread 等技术。
把jar包加入到module里边
ctrl+alt+shift+s
打开设置页面–>libraries–选择+号–>选择java–>选择要添加的jar包。选择后会弹出把这些jar包,给哪个模块使用。选择相应的模块后,点击apply应用。有几个模块需要添加的jar包的,就做几个操作。
====================添加tomcat:
每一个模块对应一个server。
配置tomcat。
tomcat configurations—>选择+号—>Tomcat server—>local—>改变端口号—>deployment—>atifact(这一步最重要,选择你的模块)。
这么配置完后就是你的模块对应相应的本地端口。
判断登录成功
这里使用到了HttpServlet。
Object.equals(a,b);a和b相等就会返回true。

文档的导入导出

WEB-INF 下边的jsp程序是无法直接访问的。
jsp文件供其他jsp文件使用的配置
在web.xml中进行配置


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值