1.JSP referer的用处

request.getHeader("Referer")得到上一次的Url,用途之一,可以作为防盗链

能得到你是从什么页面过来的,referer的用处 

在开发web程序的时候,有时我们需要得到用户是从什么页面连过来的,这就用到了referer。

它是http协议,所以任何能开发web程序的语言都可以实现,比如jsp(SUN企业级应用的首选)中是:

request.getHeader("referer");

php(做为现在的主流开发语言)是$_SERVER['HTTP_REFERER']。其他的我就不举例了(其实是不会其他的语言)。

那它能干什么用呢?我举两个例子:

1,防止盗连,比如我是个下载软件的网站,在下载页面我先用referer来判断上一页面是不是自己网站,如果不是,说明有人盗连了你的下载地址。

2,电子商务网站的安全,我在提交信用卡等重要信息的页面用referer来判断上一页是不是自己的网站,如果不是,可能是黑客用自己写的一个表单,来提交,为了能跳过你上一页里的javascript的验证等目的。

使用referer的注意事项:

如果我是直接在浏览器里输入有referer的页面,返回是null(jsp(SUN企业级应用的首选)),也就是说referer只有从别的页面点击连接来到这页的才会有内容。

我做了个实验,比如我的referer代码在a.jsp(SUN企业级应用的首选)中,它的上一页面是b.htm,c.htm是一个带有iframe的页面,它把a.jsp(SUN企业级应用的首选)嵌在iframe里了。我在浏览器里输入b.htm的地址,然后点击连接去c.htm,那显示的结果是b.htm,如果我在浏览器里直接输入的是c.htm那显示的是c

2、Java获取请求客户端的真实IP地址 

通常通过request.getRemoteAddr() 

取得客户端的IP地址,做鉴权和校验,逻辑没问题,那么肯定request.getRemoteAddr()出了问题,google下,发现有人遇到类似的问题。 

最终定位为request.getRemoteAddr()这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。 

如果使用了反向代理软件,将http://192.168.1.110:2046/ 

的URL反向代理为http://www.xxx.com/ 

的URL时,用request.getRemoteAddr() 
方法获取的IP地址是:127.0.0.1 或 192.168.1.110,而并不是客户端的真实IP。 

经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR 

信息用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。 
Java代码 
  

程序代码 程序代码
public String getIpAddr(HttpServletRequest request) {     
      String ip = request.getHeader("x-forwarded-for");     
      if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {     
         ip = request.getHeader("Proxy-Client-IP");     
     }     
      if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {     
         ip = request.getHeader("WL-Proxy-Client-IP");     
      }     
     if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {     
          ip = request.getRemoteAddr();     
     }     
     return ip;     
}    

    public String getIpAddr(HttpServletRequest request) {  
       String ip = request.getHeader("x-forwarded-for");  
       if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
          ip = request.getHeader("Proxy-Client-IP");  
      }  
       if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
          ip = request.getHeader("WL-Proxy-Client-IP");  
       }  
      if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
           ip = request.getRemoteAddr();  
      }  
      return ip;  

}  

3.jsp 下载txt文件和excel文件

最近做了个用jsp下载的页面 将代码贴出来 权作记录吧

1 下载txt文件 

这个花了我不少时间 原因是用ie下载txt文件时是在页面中直接打开了文件.虽然查了一些资料,也看了别人的解决方案,可还是解决不了问题,最后发现是一个字母惹的祸:少写一个字母 嘿嘿 够马虎!!!

代码如下:

OutputStream o=response.getOutputStream();
   byte b[]=new byte[500];
   File fileLoad=new File("e:/test.txt");
    response.setContentType("application/octet-stream");

   response.setHeader("content-disposition","attachment; filename=text.txt");
   long fileLength=fileLoad.length();
   String length1=String.valueOf(fileLength);
   response.setHeader("Content_Length",length1);
   FileInputStream in=new FileInputStream(fileLoad);
   int n;
   while((n=in.read(b))!=-1){
    o.write(b,0,n);
   }
  
   in.close();
   out.clear();
   out = pageContext.pushBody();

2 下载excel文件 

跟下载txt文件时的唯一区别是ContentType值的设置不同:

OutputStream o=response.getOutputStream();
   byte b[]=new byte[500];
   File fileLoad=new File("e:/text.xls");
   response.reset();
  

    response.setContentType("application/vnd.ms-excel");

   response.setHeader("content-disposition","attachment; filename=text.xls");
   long fileLength=fileLoad.length();
   String length1=String.valueOf(fileLength);
   response.setHeader("Content_Length",length1);
   FileInputStream in=new FileInputStream(fileLoad);
   int n;
   while((n=in.read(b))!=-1){
    o.write(b,0,n);
   }
  
   in.close();
   out.clear();
   out = pageContext.pushBody();



这两个本来是放在一起的,因为我的页面中需要判断是下载的txt文件还是xls文件  在这里给分开了 需要注意的是,最后两句一定要加上,否则会出现getOutputStream()错误的!!!!









实例:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <base href="<%=basePath%>">
    <title>My JSP 'index.jsp' starting page</title>
    <script type="text/javascript">
       function download(filename){
         var url = encodeURI("down2.jsp?filename="+filename);
         window.location.href= url;
       }
    </script>
</head>

<body>
普通测试:
<a href="javascript:void(0)" onclick="download('a.txt');">Down a.txt</a>   
中文文件名测试:
<a href="javascript:void(0)" onclick="download('中文.txt');">Down 中文.txt</a>   
普通转向:
<a href="a.txt">down.txt</a>   
</body>
</html>


down2.jsp:
<%@ page language="java" import="java.util.*,java.io.* " pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("utf-8");
String filename = request.getParameter("filename");
filename = new String(filename.getBytes("ISO-8859-1"),"UTF-8"); 
System.out.println(filename);
OutputStream o=response.getOutputStream();
byte b[]=new byte[500];
/** * 得到文件的当前路径 * @param args */ 
String   serverpath=request.getRealPath("\\"); 
File fileLoad=new File(serverpath+filename);
response.setContentType("application/octet-stream");
response.setHeader("content-disposition","attachment; filename="+filename);
long fileLength=fileLoad.length();
String length1=String.valueOf(fileLength);
response.setHeader("Content_Length",length1);
FileInputStream in=new FileInputStream(fileLoad);
int n;
while((n=in.read(b))!=-1){
   o.write(b,0,n);
}
in.close();
out.clear();
out = pageContext.pushBody();
%>