WEB17_Request对象

本节概要:

1.请求行,获得信息的方法

2.请求头,获得信息的方法;防盗链

3.请求体,获得信息的方法

4.其他:登录的信息回显

 

首先,可以抓包想一下请求行、头、体能获得到那些信息?

这里我默写一下

请求行:GET\POST  /WEB应用名/.. 协议

请求头:各项数据

请求体:GET没有,POST表单提交的数据键值对

 

请求行

protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		//获取请求表单的提交方式
		String method = request.getMethod();
//获取应用名称
		String name = request.getContextPath();
		//获取请求表单的URI
		String uri = request.getRequestURI();
		//获取请求表单的URL
		StringBuffer url = request.getRequestURL();
		//获取请求表单的协议
		String protocol = request.getProtocol();
		System.out.println("method:"+method+"\nURI:"+uri+"\nURL:"+url+"\nProtocol:"+protocol);;
	}

其中最常用到的是:getContextPath()。我们可以借用其动态的做一些事情,比如说什么时候你突然修改了项目的名称,这会导致一些你在项目中写死的一些带有项目名称的代码出错,我们这是就可以利用这个方法动态获得项目的名称了!

另外顺带说一下,获得客户端的IP的代码

String addr = request.getRemoteAddr();

请求头

这个方法比较多,我们一般使用的是getHeader(String)

protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
//		getHeader演示
		String user_agent = request.getHeader("User-Agent");
//		获得所有的头名称
		Enumeration names = request.getHeaderNames();
		//取出头名称
		while(names.hasMoreElements()){
			String name = (String) names.nextElement();
//			配合getHeader()输出全部头及其值
			String value = request.getHeader(name);
			System.out.println(name+":"+value);
		}
		System.out.println(user_agent);
	}

另外,讲一下防盗链。

这个技术需要依靠一个请求头里的key。即referer。

referer是什么?就是比如说你通过百度去百度新闻,从百度发送请求,则referer是百度的地址,通过网易去百度新闻,从网易发送请求,则referer就是网易的地址。而防盗链就是我们获得了这个referer,然后判断一下请求的地址是不是,我们自己的网站,不是我就显示另一个页面,防止页面的盗取。

代码如下

//设置中文
		response.setContentType("text/html;charset=UTF-8");
		//防盗链
		String referer = request.getHeader("referer");
		System.out.println(referer);
		if(referer.startsWith("http://localhost")){
			response.getWriter().write("欢迎你的到来!");
		}else{
			response.getWriter().write("请从正确地址进入!");
		}

请求体

1.getParameter(String):重要

2.getParameterValues(String) 我们通过这个方法获得类似于Checkbox这样的同一个name多个value。

3.getParameterNames()

4.getParameterMap():重要

//post:设置编码格式
		request.setCharacterEncoding("UTF-8");
		//获得单个表单值
		String username = request.getParameter("username");
		System.out.println(username);
		//获得多个表单值
		String[] hobbys = request.getParameterValues("hobby");
		for(String hobby:hobbys){
			System.out.println(hobby);
		}
		//获取多个表单的key
		Enumeration names = request.getParameterNames();
		while(names.hasMoreElements()){
			System.out.println(names.nextElement());
		}
		//获得一个map
		Map<String,String[]> map = request.getParameterMap();
		for(Map.Entry<String, String[]> me:map.entrySet()){
			//获取key值
			System.out.println(me.getKey());
			//遍历获取value
			for(String str:me.getValue()){
				System.out.println(str);
			}
		}

BeanUtil的使用

什么是BeanUtil呢?

其实就是一个程序员自己偷懒作品   先贴出来Jar包>>>

提取码:d21j 
现在说一下在哪里偷懒!

首先,我们从表单拿数据要怎么拿呢?

我们可以使用getParameter()方法拿啊!那要是表单传的数据太多了呢,比如我们表单要传十个数据,那我们要写是个getParameter()么?

我们怎么办?我们懒啊!于是我们就依据OO(Object Oriented)思想,将这些数据封装到一个对象中。

BeanUtil的思想就是我们有一个对象,这里我们一般使用那个我们定义的domain包的对象,有时也称POJO

使用这个User类来作为封装对象。

好像有点说不明白,贴一下代码吧!

//设置编码类型
		response.setContentType("text/html;charset=UTF-8");
		request.setCharacterEncoding("UTF-8");
		//BeanUtil封装对象
		Map<String,String[]> map = request.getParameterMap();
		User user = new User();
		try {
			BeanUtils.populate(user, map);
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

我们首先看到要用到这个很重要的getParameterMap()方法,因为数据都在这里呗。

然后还有User,因为我们即将将其作为数据存储对象呗。

然后使用BeanUtil类的populate方法了,而这个populate方法的功能就是将你的那个表单的name的value值相等的User类里的各个值传值!

解释有点困难,贴代码!先看html里的代码,这里我们看表单里的name属性,这里例如account

再看我们的domain包的User类

这里可以看出,User类里的account和表单上的name="account"这两个值都是一样的!

只有这样的我们才能将值传到user对象里!

其他

request对象域

类似与ResponseContext域,这个域的功能差不多。列一些不同。

 

ResponseContext域:

创建:服务器启动

销毁:服务器关闭

范围:整个Web应用

Request域:

创建:访问开始

销毁:响应结束

访问:此次请求

UUID的使用

UUID这里我们使用其功能是生成一个随机的32位的字符串,在哪里用呢?我们数据库的主键ID可以用到啊!而且大公司一般都是这样用的。

UUID uu = UUID.randomUUID();
System.out.println(uu);

如果你数一下位数会看出来,其实是36位,因为Java会添加四个-。

转发功能

写贴出代码

//服务器内部转发,获取转发对象
		RequestDispatcher dispatcher = request.getRequestDispatcher("/headServlet");
		//进行转发
		dispatcher.forward(request, response);

这里可以看出,我的url地址栏上显示的是这个dispatcherServlet的地址,但其实是转发到了服务器的headServlet这个地址,显示的是其内部的内容。

转发与重定向的区别:

1.重定向请求两次,转发请求一次

2.重定向地址栏变化,转发地址栏不变

3.重定向可以访问外部服务器,转发只可以访问内部服务器

4.转发性能优于重定向

服务器端地址:不需要写web应用名称

客户端地址:需要写web应用名称

 

另外,进行注册界面书写时,注册完成跳转页面要使用重定向,即serRedirect()方法。

登录失败回显

这里我们需要使用到jsp写的界面,而HTML和JSP的一个不同之处就是JSP可以在<%%>里书写Java代码。

然后我们就可以通过request来确认是否显示账户密码错误了!

简单说一下原理,在登录的servlet里面我们有判断是否登录成功的代码,然后判断出来登陆失败的话,我们就使用转发功能,将request对象添加一个键值对比如

key:loginInfo   value:"账户密码错误!"

然后我们就转发给login页面,这时候在login页面里我们使用一个div来显示账户密码错误的信息,在div里写入Java代码<%= request.getAttribute("loginInfo")==null?"":request.getAttribute("loginInfo") %>由此只要我们一转发给login页面,就会在此div里显示账户密码错误。实现了回显!

代码:

protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
//		响应内容类型
		response.setContentType("text/html;charset=UTF-8");
		request.setCharacterEncoding("UTF-8");
		//获取表单信息
		String account = request.getParameter("uaccount");
		String password = request.getParameter("upassword");
		//处理表单消息
		boolean result = loginDao.dealMessage(account,password);
		PrintWriter out = response.getWriter();
		//登录结果处理
		if(result){
			loginSuccess(out, account);
		}else{
			request.setAttribute("loginInfo", "用户名密码错误!");
			request.getRequestDispatcher("/cz/login.jsp").forward(request, response);
		}
	}

这里主要看的是登录失败,也就是最后几行的处理。我们使用request域装入了一对键值对,然后将request转发给了服务器内部的login.jsp

我们就可以在login里拿到request对象的数据了

我们在login.jsp里的div里接受一下数据

<div class="row">
	<%= request.getAttribute("loginInfo")==null?"":request.getAttribute("loginInfo") %>
</div>

于是数据就显示在了页面上

另外,我还出现了一些错误,当我转发给login.jsp的时候,css样式表丢失了。打开F12可以看到,404错误,这就是路径的问题。

看一下这个请求网址,在看一下我的项目结构,我们可以知道请求网址应该是:http://localhost:8080/WEB05/css/mycss.css

开始,我的路径是这样的。

<link rel="stylesheet" href="../css/mycss.css">

我的登录本来是Html代码后来改的jsp。所以路径没有变动,本来没有事的,可是一转发路径就变了。

我在网上找了一些方法,但是都没有说的清除,这里我自己写一遍。

修改方法:

在login.jsp的最上边加上这些代码

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

就是设置基本路径在哪里的,现在我们访问的话,其实还是404,因为我们还需要改一下上边代码设置的基本路径,这里我们看basePath这一行,那些方法别看,主要看最后是path+"/"也就是说把我们的路径设置为了/,但实际上呢?我们应该是WEB/css啊!

好吧,我写着博客,然后想把路径先改到原先错误的地方,截几张图再发到博客上,结果代码改回去就忘了怎么改回来了。于是,我自闭了。最后,我发现直接将css的href地址改成绝对地址就行了。类似这样的

<link rel="stylesheet" href="/WEB05/css/mycss.css">

这个WEB05从上边的项目结构图来看,就是我的根目录。反正我自闭了,再见!

本节概要:

1.请求行,获得信息的方法

2.请求头,获得信息的方法;防盗链

3.请求体,获得信息的方法

4.其他:登录的信息回显

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值