如何阻止http splitting 的java http代码代码

7384人阅读
java(123)
设计模式(25)
& & 单例模式相信大家都知道,用过的人不在少数。之前写过一篇博文《singleton模式四种线程安全的实现》(参见:http://blog.csdn.net/u/article/details/),讲诉了单例模式的四种写法,并指出占位符模式的写法比较ok,详见如下:package com.effective.
public class Elvis
private static boolean flag =
private Elvis(){
static class SingletonHolder{
private static final Elvis INSTANCE = new Elvis();
public static Elvis getInstance()
return SingletonHolder.INSTANCE;
public void doSomethingElse()
}& & 但这都是基于一个条件:确保不会通过反射机制调用私有的构造器。& & 这里举个例子,通过JAVA的反射机制来“攻击”单例模式:package com.effective.
import java.lang.reflect.C
import java.lang.reflect.InvocationTargetE
public class ElvisReflectAttack
public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException
Class&?& classType = Elvis.
Constructor&?& c = classType.getDeclaredConstructor(null);
c.setAccessible(true);
Elvis e1 = (Elvis)c.newInstance();
Elvis e2 = Elvis.getInstance();
System.out.println(e1==e2);
}& &运行结果:false& &可以看到,通过反射获取构造函数,然后调用setAccessible(true)就可以调用私有的构造函数,所有e1和e2是两个不同的对象。& &如果要抵御这种攻击,可以修改构造器,让它在被要求创建第二个实例的时候抛出异常。& &经修改后:package com.effective.
public class ElvisModified
private static boolean flag =
private ElvisModified(){
synchronized(ElvisModified.class)
if(flag == false)
throw new RuntimeException(&单例模式被侵犯!&);
static class SingletonHolder{
private static final ElvisModified INSTANCE = new ElvisModified();
public static ElvisModified getInstance()
return SingletonHolder.INSTANCE;
public void doSomethingElse()
}& & 测试代码:package com.effective.
import java.lang.reflect.C
public class ElvisModifiedReflectAttack
public static void main(String[] args)
Class&ElvisModified& classType = ElvisModified.
Constructor&ElvisModified& c = classType.getDeclaredConstructor(null);
c.setAccessible(true);
ElvisModified e1 = (ElvisModified)c.newInstance();
ElvisModified e2 = ElvisModified.getInstance();
System.out.println(e1==e2);
catch (Exception e)
e.printStackTrace();
}& & 运行结果:Exception in thread &main& java.lang.ExceptionInInitializerError
at com.effective.singleton.ElvisModified.getInstance(ElvisModified.java:27)
at com.effective.singleton.ElvisModifiedReflectAttack.main(ElvisModifiedReflectAttack.java:17)
Caused by: java.lang.RuntimeException: 单例模式被侵犯!
at com.effective.singleton.ElvisModified.&init&(ElvisModified.java:16)
at com.effective.singleton.ElvisModified.&init&(ElvisModified.java:7)
at com.effective.singleton.ElvisModified$SingletonHolder.&clinit&(ElvisModified.java:22)
... 2 more& & 可以看到,成功的阻止了单例模式被破坏。& & 从JDK1.5开始,实现Singleton还有新的写法,只需编写一个包含单个元素的枚举类型。推荐写法:package com.effective.
public enum SingletonClass
public void test()
System.out.println(&The Test!&);
}& & 测试代码:package com.
import java.lang.reflect.C
import java.lang.reflect.InvocationTargetE
import com.effective.singleton.SingletonC
public class TestMain
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
Class&SingletonClass& classType = SingletonClass.
Constructor&SingletonClass& c = (Constructor&SingletonClass&) classType.getDeclaredConstructor();
c.setAccessible(true);
c.newInstance();
}& & 运行结果:Exception in thread &main& java.lang.NoSuchMethodException: com.effective.singleton.SingletonClass.&init&()
at java.lang.Class.getConstructor0(Unknown Source)
at java.lang.Class.getDeclaredConstructor(Unknown Source)
at com.effective.TestMain.main(TestMain.java:22)& & 由此可见这种写法也可以防止单例模式被“攻击”。& & 而且这种写法也可以防止序列化破坏单例模式,具体不在举例了,有关序列化以及单例模式被序列化破坏可以参考博文《JAVA序列化》(链接:http://blog.csdn.net/u/article/details/)。& & 单元素的枚举类型已经成为实现Singleton模式的最佳方法。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:729744次
积分:8963
积分:8963
排名:第2111名
原创:188篇
转载:15篇
评论:633条
内推简历请砸:
zhuzhonghua.。
消息中间件交流可以加微信:hiddenzzh。
文章:55篇
阅读:96827
阅读:33599
文章:12篇
阅读:33273
文章:26篇
阅读:76271
文章:28篇
阅读:141962
文章:47篇
阅读:228552
(4)(4)(4)(6)(10)(6)(8)(6)(5)(5)(6)(4)(5)(5)(5)(9)(20)(34)(11)(10)(14)(11)(3)(4)(6)(1)利用java代码和web拦截器轻松实现一个app抓包工具 - 简书
利用java代码和web拦截器轻松实现一个app抓包工具
目前app测试时我们需要对接口数据进行抓包,对于app的抓包,我们可以使用很多现成的工具,比如fiddler、wireshark、charles等,基本上可以满足要求,但是对于一些定制化的需求,比如说:我们需要将抓包的数据进行篡改后再发送到服务器,或者对请求的数据新增标志字段以便定位问题,或者更多需要更改数据的需求,传统抓包工具已经很难实现,需要我们探索新的方式方法。
我们知道,一般的抓包工具都是使用代理的方式来截取请求,然后以ui的方式展现出来,我们本次也直接使用这种代理的方式来实现抓包,然后对抓取的包进行数据的重组和处理后再发送到原本请求的服务器获取结果返回给app即可。整个流程如下(此流程仅适用于http、https协议):
说明:代理服务器抓取到app到服务器之间的包,进行解包之后,对数据进行处理(更改或者新增)后再次进行数据封包,将封包后的数据发送到原服务器之后将数据返回给app即可,这期间我们在解包之后可以看到数据的具体信息。
整个系统最核心的内容无疑为代理服务器,甚至有些人对数据的解包和封包和再次发送感觉实现起来很难。如果app的请求为http协议,其实我们可以使用现成的工具,最直接的就是将代理服务器伪装成一个web服务器,app发送给web服务器的数据可以直接被web服务器解包,之后可以使用httpclient再次模拟客户端做封包操作发送给app:数据拦截:web拦截器数据解包:servlet(request)数据处理:自助java类数据再封包和发送:httpclient数据的接收:httpclient数据返回app:servlet(response)整个流程变为:
下面我们从代码层面来说明整个过程:1.搭建一个web的服务器环境2.写一个拦截器
3.代理服务器代码packagecom.pingan.testcloud./*** ClassName:LoginFilter** @Description:过滤器,白名单里所有接口都要先经过此过滤器,白名单请在web.xml中设置* @author dingjingjing058* @date 日*/importjava.io.IOEimportjava.io.PrintWimportjava.net.URLDimportjava.net.URLEimportjava.util.ArrayLimportjava.util.Eimportjava.util.HashMimportjava.util.Limportjava.util.Mimportjavax.servlet.Fimportjavax.servlet.FilterCimportjavax.servlet.FilterCimportjavax.servlet.ServletEimportjavax.servlet.ServletRimportjavax.servlet.ServletRimportjavax.servlet.http.HttpServletRimportjavax.servlet.http.HttpServletRimportjavax.servlet.http.HttpSimportorg.slf4j.Limportorg.slf4j.LoggerFimportcom.pingan.testcloud.httphelper.BasicPimport com.pingan.testcloud.httphelper.HttpClientHimportcom.pingan.testcloud.httphelper.ResponsePpublic classLoginFilter implements Filter {publicLogger logger = LoggerFactory.getLogger(this.getClass());@Overridepublic void destroy() {// TODO Auto-generated method stub}@SuppressWarnings("rawtypes")@Overridepublic void doFilter(ServletRequest req,ServletResponse res, FilterChain chain)throws IOException,ServletException {HttpServletRequest request =(HttpServletRequest)HttpServletResponse response =(HttpServletResponse)request.setCharacterEncoding("UTF-8");//获得用户请求的URI,并进行截取String url= request.getRequestURI();String[] path =url.split("/");// System.out.println(path);Enumerationenu=request.getParameterNames();String paraString="";while(enu.hasMoreElements()){StringparaName=(String)enu.nextElement();paraString=paraString+paraName+":"+request.getParameter(paraName)+"";}<("用户请求地址为:"+url+"请求参数为:"+paraString);if(ConfigReader.getWhiteListMap().get(path[path.length-1])==null){//如果不在白名单,则进行如下校验String method=request.getMethod();if(method.equals("POST"))method="post";elseif(method.equals("GET"))method="get";BasicParameter bp1 = newBasicParameter(url,"get","FILTER");enu=request.getParameterNames();while(enu.hasMoreElements()){String paraName=(String)enu.nextElement();bp1.addParamters(paraName,request.getParameter(paraName));Enumerationen=request.getHeaderNames();Map headers=newHashMap();while(en.hasMoreElements()){//取出信息名String name=(String)en.nextElement();//取出信息值String value=request.getHeader(name);headers.put(name, value);}bp1.setHeaders(headers);}List rps= new ArrayList();try {HttpClientHelper client=newHttpClientHelper(request.getServerName(),request.getServerPort(),"http");client.addHttpRequest(bp1);rps=client.run();} catch (Exception e1) {// TODO Auto-generatedcatch blocke1.printStackTrace();}for(Map.Entryen:rps.get(0).getHeaders().entrySet()){response.addHeader(en.getKey(),en.getValue());}response.setContentType("text/html");response.setCharacterEncoding("UTF-8");PrintWriter out =response.getWriter();out.print(rps.get(0).getRespdata());out.flush();out.close();//response.sendRedirect("./login.html");//chain.doFilter(request,response);//已经登陆,继续此次请求}else{//在白名单里,继续此次请求chain.doFilter(request,response);}}@Overridepublic void init(FilterConfig config)throws ServletException {}}注意:1.代码中使用了httpclient,具体代码封装请参加技术文档。2.对于解包后的数据操作未做详细讲解,可以参考sevlet技术文档。最后,对手机设置网络代理,代理指向web服务器的ip和端口,试试效果吧。}

我要回帖

更多关于 httpclient java 代码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信