打个广告,帮朋友卖点东西,东西超便宜的哟【衣服鞋子等】,厂家直接出货,绝对低于市场价!!! 一般都比市场价便宜3—7折【都是牌子货】,如果您感兴趣,可以扫描屏幕下方的二维码,感谢关注!!!
一、request和response
1、request
1.获取环境信息
public class ServletRequest extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
test1(request);
}
//获取环境信息
private void test1(HttpServletRequest request) {
//uri是url的子集
System.out.println(request.getRequestURL());//得到请求url地址;http://localhost:8080/day08/servlet
System.out.println(request.getRequestURI());//得到请求的资源;/day08/servlet
//得到来访者的ip
System.out.println(request.getRemoteAddr());
//http:.......servlet?name=sax
System.out.println(request.getQueryString());//返回name=sax
System.out.println(request.getRemoteHost());//返回客户机的主机名,
System.out.println(request.getRemotePort());//返回客户机网络端口号
System.out.println(request.getLocalAddr());//返回服务器的ip
System.out.println(request.getLocalName());//返回服务器的主机名
//返回请求方式
System.out.println(request.getMethod());//get,post
}
2.获取请求头
//获取请求头
private void test2(HttpServletRequest request) {
//该方法只获取一个值(第一个)
String head=request.getHeader("Accept-Encoding");//获取支持的压缩格式
if(head.contains("gzip")){//获取支持的压缩格式
//输出压缩数据
}else{
//输出不压缩数据
}
//获取指定名称的头的所有值
Enumeration e=request.getHeaders("Accept-Encoding");
while(e.hasMoreElements()){
String value=(String) e.nextElement();
System.out.println(value);
}
//获取所有请求头的名称和值
e=request.getHeaderNames();
while(e.hasMoreElements()){
String name=(String) e.nextElement();
String value=request.getHeader(name);
}
}
3.获取请求数据
//获取客户机的请求数据
private void test3(HttpServletRequest request) {
//localhost......?name=sax
String value=request.getParameter("name");//返回sax
//localhost.....?like=string&like=hhhd
String likes[]=request.getParameterValues("like");
for(int i=0;likes!=null&&i<likes.length;i++){//防止空指针
System.out.println(likes[i]);
}
localhost.....?name=string&password=hhhd
Enumeration e=request.getParameterNames();
while(e.hasMoreElements()){
String name=(String) e.nextElement();
value=request.getParameter(name);
System.out.println(name+"="+value);
}
//name=sax&like=ss&like=ff,框架中常用
Map<String, String[]> map=request.getParameterMap();
for(Entry<String, String[]> me:map.entrySet()){
String name=me.getKey();
String[] v=(String[])me.getValue();
System.out.println(name+"="+v[0]);
}
}
4.常见问题
1.数据检查
//检查数据是否为空
private void test4(HttpServletRequest request) {
//localhost......?name=sax
String value=request.getParameter("name");//返回sax
if(value==null||value.trim().equals(""))//null ;""; " ";都不行,trim()表示去掉字符串中的空格
{System.out.println("不行");}
}
2.提交中文数据
//数据为中文,浏览器以哪个码表打开提交的数据就是哪个码表,
private void test5(HttpServletRequest request) throws IOException {
//post方式,setCharacterEncoding对get无效
//localhost......?name=中国
request.setCharacterEncoding("UTF-8");//在编写网页时控制浏览器编码方式为UTF-8
String value=request.getParameter("name");//返回中国
System.out.println(value);
//get方式
byte source[]=value.getBytes("iso8859-1");//得到客户机提交的原始数据(Tomcat默认)
value=new String(source,"UTF-8");//UTF-8是浏览器提交的编码方式
System.out.println(value);
}
注意:该方法不建议使用,get方式乱码还可以通过改服务器配置service.xml来解决
方法1:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8"/>
方法2:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" useBodyEncodingForURI="true"/>
但是该方法还是要依赖环境(Tomcat服务器),也不推荐,而如果采用url编码则可以解决以上问题。浏览器中两次URL编码。服务器中自己再做一次URL解码。
3.请求的转发
//用request实现请求转发
private void test4(HttpServletRequest request) {
String data="asda";
//11this.getServletContext().setAttribut("data",data);//开发中不能用这个取数据(并发)
//22
request.setAttribute("data",data);//因为每次访问都创建一个request,故不会有并发问题
//方法1
RequestDispatcher rd = request.getRequestDispatcher("/test.jsp");
rd.forward(request, response);
/*方法2:用servletContext
ServletContext context = this.getServletContext();
RequestDispatcher rd = context.getRequestDispatcher("/test.jsp");
rd.forward(request, response); //相当于调用ServletDemo2的doget(),故地址栏不变
*/
}
在test.jsp中
<body>
<%
//对应11
//String data=(String)this.getServletContext.getAttribut("data");
//out.write(data);
//对应22
String data=(String)request.getAttribut("data");
out.write(data);
%>
</body>
注意:
1、在forward(req,res)之前的输出数据缓存区中的内容都会被清掉,响应头中的数据不会被清掉。
2、获取当前web应用的名称可以用request.contextPath来获取
3、请求转发除了forward之外还有include,用来包含另外一个servlet
//用request实现请求转发
private void test4(HttpServletRequest request) {
request.getRequestDispatcher("/head").include(request, response);
response.getWriter().write("<br/>adf<>br/>")
request.getRequestDispatcher("/foot").include(request, response);
}
注意:包含不会清除之前的输出数据缓存区中的内容。
2、response
1.基本方法
在HttpServletresponse中封装了向客户端响应的响应状态码、响应头和数据(参照HTTP协议)
方法 | 含义 |
setStatus(int sc) | 设置状态码 |
setHeader(String name,String value) | 设置响应头 |
getWriter() | 获取字符流 |
getOutprintStream() | 获取字节流 |
注意:getWriter()方法和getOutprintStream()方法互斥,只能调用一个方法。(注意在servlet的转发中可能碰到)
2.常见应用
1.输出文字
通过字节流
public class ServletResponse1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
test1(response);
}
//通过字节流获取汉字
private void test1(HttpServletResponse response) throws IOException {
String data="中国";
/*
OutputStream out=response.getOutputStream();
out.write(data.getBytes());
//该代码可能出现乱码(除非字节在编码时的方式与浏览器打开的时的编码方式相同)
//详细原理:
* out.write(data.getBytes())=
* bety b[]=data.getBytes();采用gb2312保存到b[]
* out.write(b);
* 浏览器取出b,可能采用不同的编码
*/
//方法1
OutputStream out=response.getOutputStream();
response.setHeader("content-type", "text/html;charset=UTF-8");//告诉浏览器编码方式为UTF-8
byte b[]=data.getBytes("UTF-8");//保存形式为UTF-8
out.write(b);
/*
//方法2:模拟http响应头
OutputStream out=response.getOutputStream();
out.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'>".getBytes());
byte b[]=data.getBytes("UTF-8");//保存形式为UTF-8
out.write(b);
*/
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}
通过字符流
// 通过字符流获取汉字
private void test2(HttpServletResponse response) throws IOException {
String data = "中国";
// 告诉浏览器编码方式为UTF-8
response.setHeader("content-type", "text/html;charset=UTF-8");
// 设置response字符转换为字节时的编码方式(字符流转换为字节流这一过程response自己完成)
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();// 默认为iso8859-1
out.write(data);
}
2.文件下载
// 通过字节流下载文件
private void test3(HttpServletResponse response) throws IOException {
String realpath=this.getServletContext().getRealPath("/down/1.jpg");//获取其绝对路径,webroot路径下
String filename=realpath.substring(realpath.lastIndexOf("\\"+1));//含义看Servlet下ServletContext
response.setHeader("content-disposition", "attachment;filename="+filename);
//如果文件名是中文名,中文名要经过URL编码
//response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(filename,"UTF-8"));
FileInputStream in=new FileInputStream(realpath);//文件装载
//文件打出
int len = 0;
byte buffer[] = new byte[1024];
OutputStream out = response.getOutputStream();
while((len=in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
}
注意:读取除字符串以外的文件只能通过字节流,因为如果采用字符流可能导致数据丢失(编码转换问题)
3.生成动态图片
private void test1(HttpServletResponse response) throws IOException {
//6.通知浏览器不要缓存图片,不然回车不改变
response.setHeader("Expires", "-1");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
//5.通知浏览器以图片方式打开
response.setHeader("Content-type", "image/jpeg");
//1.在内存中创建一幅图片
BufferedImage image=new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
//2.得到图片
Graphics g=image.getGraphics();
//3.向图片上写数据
g.setColor(Color.RED);//设置背景的颜色
g.fillRect(0,0,80,20);//设置背景的颜色
g.setColor(Color.RED);//设置数字的颜色
g.setFont(new Font(null,Font.BOLD,20));
g.drawString(markNum(), 0,20);//markNum()为生成随机数的方法(生成7位数字)
//4.将图片写到浏览器
ImageIO.write(image, "jpg", response.getOutputStream());
}
private String markNum(){
Random r=new Random();
String num=r.nextInt(9999999)+"";//0-99999999
StringBuffer sb=new StringBuffer();
for(int i=0;i<7-num.length();i++)
{
sb.append("0");//在前面补零
}
num =sb.toString()+num;
return num;
}
4.定时刷新
private void test1(HttpServletResponse response) throws IOException {
response.setHeader("refresh", "5");//五秒刷新一次
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.getWriter().write("我是中国人");
}
5.请求的重定向
private void test1(HttpServletResponse response) throws IOException {
response.sendRedirect("/day06/1.html");//项目名为day06!!!
/*实际上重写了
response.setHeader("location", "/day06/1.html");
response.setStatus(302);
*/
}
注意:
1.尽量不使用重定向,因为该方法将向服务器发送两次请求
2.“/”如果是给服务器用的,则代表web工程,“/”如果是给浏览器用的,则代表webapps
private void test1(HttpServletResponse response) throws IOException {
//程序处理的是url资源,用“/”,程序读取硬盘用“\\”
//servletContent
this.getServletContext().getRealPath("/download/11.jpg");//表示项目名
//forward
this.getServletContext().getRequestDispatcher("/register.html");//表示项目名
//sendRedirct
response.sendRedirect("/day08/register.html");//表示webapps
//html <a href=""></a>
/*
<a href="/day08/servlet">点我</a>//表示webapps
*/
}
二、会话的管理
1、基本概念
1.会话的含义
会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。
2.要解决的问题
每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,程序要想办法为每个用户保存这些数据。例如:用户点击超链接通过一个servlet购买了一个商品,程序应该想办法保存用户购买的商品,以便于用户点结帐servlet时,结帐servlet可以得到用户购买的商品为用户结帐。
思考:用户购买的商品保存在request或servletContext中行不行?不行,request(保存时间仅仅为一次请求),servletContext(有并发问题)
2、保存会话
1.Cookie
Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。
2.Session
Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。
3、Cookie
1.示意图
2.常用方法
javax.servlet.http.Cookie类用于创建一个Cookie,response接口也中定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。 同样,request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie。Cookie类的方法:
- public Cookie(String name,String value)
- setValue与getValue方法
- setMaxAge与getMaxAge方法 //Cookie的有效时间,如果不设置一个会话结束(即浏览器打开和关闭的时间)
- setPath与getPath方法 //此处Path表示有效域,即指定该Cookie在哪个路径下有效(如有项目svn,下有路径servlet/Demo;可以将其设置为/svn或/svn/servlet,分别表示在其路径下有效)
- setDomain与getDomain方法
- getName方法
3.举例说明
1.显示上次访问的时间
//网站首页:可以实现显示用户上次访问时间
public class CookieDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write("这是网站首页!!<br/><br/>");
out.write("您上次访问时间是:");
//得到上次访问时间
Cookie cookies[] = request.getCookies();//获取Cookie
for(int i=0;cookies!=null && i<cookies.length;i++){
Cookie cookie = cookies[i];
if(cookie.getName().equals("lastAccessTime")){
Long time = Long.parseLong(cookie.getValue());
Date d = new Date(time);
out.write(d.toLocaleString());
}
}
//给用户以cookie的形式送最新的时间
Cookie cookie = new Cookie("lastAccessTime",System.currentTimeMillis()+"");//给lastAccessTime=当前时间
cookie.setMaxAge(10000); //保存时间(秒),不设置,一个会话结束
cookie.setPath("/day06");表示在day06这个项目下有效,如果不设,默认在该servlet访问路径同级有效,如该servlet为local.../day6/servlet/ServletCookie,则其有效路径为day6/servlet
response.addCookie(cookie);//将该cookie发给浏览器
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
2.删除Cookie(已存在浏览器中)
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Cookie cookie = new Cookie("lastAccessTime",System.currentTimeMillis()+"");
cookie.setMaxAge(0);将其保存时间设置为0
cookie.setPath("/day06");
response.addCookie(cookie);
}
4.注意事项
- 一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
- 一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
- 浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
- 如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
- 注意,删除cookie时,path必须一致,否则不会删除
5.应用举例
1.程序说明
设置一个程序,可以记录你曾经访问过的商品:首页中有所有商品,和曾经访问过的商品(显示3个),如果点击商品,进入详细页面并返回id=?(2,3,5,1,3,1),设置Cookie book=(2,3_2,5_3_2,1_5_3,3_1_5,1_3_5)
2.详细设计
首页(要获取cookie)
//首页
public class CookieDemo3 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//1.显示网站所有商品
out.write("本网站有如下书籍:<br><br>");
Set<Map.Entry<String, Book>> set = DB.getAll().entrySet();
for(Map.Entry<String, Book> me : set){
Book book = me.getValue();
out.write("<a href='/day07/servlet/CookieDemo4?id="+book.getId()+"' target='_blank'>"+book.getName()+"</a>");//target='_blank'表示在新窗口打开
out.write("<br/>");
}
//2.显示用户曾经浏览过的商品
out.write("<br/><br/>您曾经浏览过的商品:<br/>" );
Cookie cookies[] = request.getCookies();
for(int i=0;cookies!=null && i<cookies.length;i++){
Cookie cookie = cookies[i];
if(cookie.getName().equals("bookHistory")){
String bookHistory = cookie.getValue(); // 2_3
String ids[] = bookHistory.split("\\_"); //将2_4_1格式拆成2,4,1
for(String id: ids){
Book book = (Book) DB.getAll().get(id);
out.write(book.getName() + "<br/>");
}
}
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
class DB//模拟数据库,存放数据
{
private static Map<String,Book> map = new LinkedHashMap();
static{
map.put("1", new Book("1","javaweb开发","老张","一本好书"));
map.put("2", new Book("2","spring开发","老黎","一本好书"));
map.put("3", new Book("3","hibernate开发","老佟","一本好书"));
map.put("4", new Book("4","struts开发","老毕","一本好书"));
map.put("5", new Book("5","ajax开发","老张","一本好书"));
}
public static Map getAll(){
return map;
}
}
class Book{//书的属性
private String id;
private String name;
private String author;
private String description;
//alt+ shift + s
public Book() {
super();
// TODO Auto-generated constructor stub
}
public Book(String id, String name, String author, String description) {
super();
this.id = id;
this.name = name;
this.author = author;
this.description = description;
}
//get,set方法
}
详细页(要添加cookie,获取cookie)
public class CookieDemo4 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//1.根据用户带过来的id号,显示商品的详细信息
String id = request.getParameter("id");
Book book = (Book) DB.getAll().get(id);
out.write("您要查看的书的详细信息如下:<br/><br/>");
out.write(book.getId() + "<br/>");
out.write(book.getName() + "<br/>");
out.write(book.getAuthor() + "<br/>");
out.write(book.getDescription() + "<br/>");
//2.给用户回送包含当前商品id的cookie
String bookHistory = makeHistory(request,id); // 3_2
Cookie cookie = new Cookie("bookHistory",bookHistory);
cookie.setMaxAge(1*30*24*3600);
response.addCookie(cookie);
}
private String makeHistory(HttpServletRequest request, String id) {
String bookHistory = null;
Cookie cookies[] = request.getCookies();//获取Cookie
for(int i=0;cookies!=null&&i<cookies.length;i++){
if(cookies[i].getName().equals("bookHistory")){
bookHistory = cookies[i].getValue();
}
}
// bookHistory=null 1 bookHistory=1
// bookHistory=3_1_5 1 bookHistory=1_3_5
// bookHistory=3_2_5 1 bookHistory=1_3_2
// bookHistory=3_2 1 bookHistory=1_3_2
// bookHistory=null 1 bookHistory=1
if(bookHistory==null){
return id;
}
List l = Arrays.asList(bookHistory.split("\\_")); //拆分[3,4] //数组 链接
LinkedList<String> list = new LinkedList();
list.addAll(l);
if(list.contains(id)){
// bookHistory=3_1_5 1 bookHistory=1_3_5
list.remove(id);
list.addFirst(id);
}else{
if(list.size()>=3){
// bookHistory=3_2_5 1 bookHistory=1_3_2
list.removeLast();
list.addFirst(id);
}else{
// bookHistory=3_2 1 bookHistory=1_3_2
list.addFirst(id);
}
}
StringBuffer sb = new StringBuffer(); //2_3_4,合成
for(String lid: list){
sb.append(lid + "_");//每个数字后面加一个“_”
}
return sb.deleteCharAt(sb.length()-1).toString();//把最后一个“_”去掉并返回
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
4、session
1.示意图
注意:每个浏览器对应一个session(默认情况下),服务器在获取session时直接调用request.getSession方法,如果有,则调用,没有,则先创建(服务器会自己创建)
2.案例分析
做一个购物程序,用session存储用户购买的商品,在首页中有商品名称及购买链接,点击购买跳到显示所有购买过的商品页面中
显示所有商品的页面:
//首页:列出所有书
public class IndexServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
request.getSession();
out.write("本网站有如下书:<br/>");
Set<Map.Entry<String,Book>> set = DB.getAll().entrySet();
for(Map.Entry<String,Book> me : set){
Book book = me.getValue();
out.write(book.getName() + " <a href='/day07/servlet/BuyServlet?id="+ book.getId() +"'>购买</a><br/>");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
class DB
{
private static Map<String,Book> map = new LinkedHashMap();
static{
map.put("1", new Book("1","javaweb开发","老张","一本好书"));
map.put("2", new Book("2","spring开发","老黎","一本好书"));
map.put("3", new Book("3","hibernate开发","老佟","一本好书"));
map.put("4", new Book("4","struts开发","老毕","一本好书"));
map.put("5", new Book("5","ajax开发","老张","一本好书"));
}
public static Map getAll(){
return map;
}
}
class Book{
private String id;
private String name;
private String author;
private String description;
//alt+ shift + s
public Book() {
super();
// TODO Auto-generated constructor stub
}
public Book(String id, String name, String author, String description) {
super();
this.id = id;
this.name = name;
this.author = author;
this.description = description;
}
//get和set
}
处理页面:
public class BuyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String id = request.getParameter("id");
Book book = (Book) DB.getAll().get(id); //得到用户想买的书
HttpSession session = request.getSession();
List list = (List) session.getAttribute("list"); //得到用户用于保存所有书的容器
if(list==null){
list = new ArrayList();
session.setAttribute("list", list);
}
list.add(book);//不懂
//request.getRequestDispatcher("/servlet/ListCartServlet").forward(request, response);转发
resquest.sendRedirect("/day07/servlet/ListCartServlet");//重定向
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
显示购买过的商品:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
List<Book> list = (List) session.getAttribute("list");
if(list==null || list.size()==0){
out.write("对不起,您还没有购买任何商品!!");
return;
}
//显示用户买过的商品
out.write("您买过如下商品:<br>");
for(Book book : list){
out.write(book.getName() + "<br/>");
}
}
注意:以上案例仅在一次会话中有效
3.原理解析
以下分析可参照上例
服务器用session保存会话的原理是在服务器为一个浏览器创建一个session时,服务器将session的id已cookie(默认情况下一个会话就失效)的形式发送给服务器,同时自己保存该session(默认30分钟为被使用后失效),如果该浏览器再次访问该服务器,将会将session的id带给服务器,然后服务器将再行查找。
故,如果想让浏览器在关闭后仍然有效,需要:
HttpSession session = request.getSession();
Cookie cookie = new Cookie("JSESSIONID",session.getId());//获取其id
cookie.setMaxAge(30*60);
cookie.setPath("/day07");
response.addCookie(cookie);
注意:在一个地方设置即可
同时如果浏览器禁用的Cookie,将导致服务器无法正常使用session(表现为点击购买后跳转到的显示购买商品为无,本次刚点击的也不存在),可以采用URL重写方法来解决(将session的id附在url后面),在处理页面中:
【
URL重写:
- response. encodeRedirectURL(java.lang.String url) :用于对sendRedirect方法后的url地址进行重写。
- response. encodeURL(java.lang.String url):用于对表单action和超链接的url地址进行重写
】
//request.getRequestDispatcher("/servlet/ListCartServlet").forward(request, response);//原
String url = response.encodeRedirectURL("/day07/servlet/ListCartServlet");//显示交给其去处理
System.out.println(url);
response.sendRedirect(url);
如此修改后可以显示本次点的的商品(但之前的不存在),如果列出所有的购买过的商品,修改显示所有商品的页面:
out.write("本网站有如下书:<br/>");
Set<Map.Entry<String,Book>> set = DB.getAll().entrySet();
for(Map.Entry<String,Book> me : set){
Book book = me.getValue();
//out.write(book.getName() + " <a href='/day07/servlet/BuyServlet?id="+ book.getId() +"'>购买</a><br/>");
String url = "/day07/servlet/BuyServlet?id=" + book.getId();//在day07项目下
url = response.encodeURL(url);
out.println(book.getName() + " <a href='"+url+"'>购买</a><br/>");
注意:如果浏览器不禁用Cookie,URL将不会被重写(服务器自己判断),重写并不能实现关闭浏览器后再打开还有信息
4.常见应用
- 使用Session完成用户登陆
- 利用Session防止表单重复提交
- 利用Session实现一次性验证码
以实现验证码为例:
有登陆页面login.html其中有随机验证码图片,在进入该页面时服务器将产生一个随机数保存在session中,同时将其显示在图片中,用户填写后提交,服务器在和session中的值进行对比
login.html
<form action="/day07/servlet/LoginServlet2" method="post">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
认证码:<input type="text" name="checkcode"><img src="/day07/servlet/ImageServlet"><br/>
<input type="submit" value="登陆">
</form>
ImageServlet(参加response中的生成动态图片)
LoginServlet2
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String checkcode = request.getParameter("checkcode");
String s_checkcode = (String) request.getSession().getAttribute("checkcode");
if(checkcode==null || s_checkcode==null || !checkcode.equals(s_checkcode)){
System.out.println("认证码错误!!");
return;
}
//得到用户名和密码,帮用户完成登陆
}