学习J2EE路途中一些有用的知识点(一)真正的干货

来源:互联网 发布:淘宝网十字绣新款 编辑:程序博客网 时间:2024/05/21 11:11

      目前在学习J2EE的一些知识,因为老是听别人说SSH框架如何如何的好,但是自己又不知道这到底是怎么一回事,所以就打算从头把Web的一些知识好好的学习学习,就在学习的过程中,整理了一些相对比较容易忘记和重要的知识点。

      1:输出中文内容防止乱码(有五种方法,但是下面记录最简单的吧)

response.setContentType("txt/html;charset=UTF-8");

       2:字符输出流和字节输出流不能同时存在。 比如:

response.getWriter().write("你好");response.getOutputStream().write("你好".getBytes());
3:获取资源文件的方法(这里以在src下面的properties资源为例子,方法的优点缺点都写了)
* 1:ServletContext (任意文件,任意位置的,但是要在web环境下) 
* 2:ResourceBundle  (这种只能获取后缀为properties 的资源) * 3:类加载器        (任意文件,任意位置的)
public void test11(){//第一种方法//ServletContext servletContext = this.getServletContext();////得到资源路径//String path = servletContext.getRealPath("/WEB-INF/classes/hnu/scw/properce/p1.properties");//    Properties properties = new Properties();//    try {//    //加载资源//properties.load(new FileReader(path));//} catch (FileNotFoundException e) {//// TODO Auto-generated catch block//e.printStackTrace();//} catch (IOException e) {//// TODO Auto-generated catch block//e.printStackTrace();//}//    String name = properties.getProperty("name");//    System.out.println(name);    //第二种方法//    ResourceBundle rbBundle = ResourceBundle.getBundle("hnu.scw.properce.p1");//    String name = rbBundle.getString("name");//    System.out.println(name);    //第三种方法/* * 拿到类加载器有三种方法   * 1:类名   如:ServletDemon1.class.getClassLoader() * 2:对象名  如:this.getClass().getClassLoader()  这种最简单 * 3:Class.forName()  如:Class.forName("ServletDemon1").getClassLoader() *///   InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("hnu/scw/properce/p1.properties");//   Properties pp = new Properties();//   try {//pp.load(inputStream);//} catch (IOException e) {//// TODO Auto-generated catch block//e.printStackTrace();//}//   String name = pp.getProperty("name");//   System.out.println(name);
         4: request对象的一些方法

5:随机验证码的生成(主要是对画笔类的掌握)

/* * 生成验证码 */private void getYanZhengMa(HttpServletResponse response) {//设置一下颜色数组,为了验证码更加难辨认Color[] yanse = {Color.RED ,Color.BLACK ,Color.GREEN , Color.BLUE};//初始化验证码的宽和高int width = 100 ;int height = 60;//初始化图片缓冲器BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB) ;//初始化画笔Graphics gp  = bi.getGraphics(); //这里是用图片来进行初始化,否则不知道是画在哪里//设置画笔颜色gp.setColor(Color.RED);  //画一个矩形的外框gp.drawRect(0, 0, width, height);//设置矩形填充的颜色gp.setColor(Color.YELLOW);//填充背景(下面是从1,1开始填充,如果从0,0开始,那么外框也会被修改了,后面-2也是同理)gp.fillRect(1, 1, width-2, height-2);//生成要填充的内容Random random  = new Random();//设置验证码的干扰线(这是为了效果来进行开发的,可以没有)gp.setColor(Color.BLUE);//画30条干扰线for(int i=0 ; i<30 ;i++){gp.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));    //下面的是画点//gp.drawOval(random.nextInt(width), random.nextInt(height), 2, 2);}//设置填充的内容的颜色gp.setColor(Color.RED);//设置填充内容的大小gp.setFont(new Font("幼圆", Font.BOLD + Font.ITALIC, 20));//如果填充的内容要为中文的时候,需要这样处理String content ="全国我觉得嘎斯的获奖情况大手笔的吧区隔化akshldeqw";//要把上面的转为unicode编码,因为如果浏览器不支持中文的话就会出现乱码,如果在国内的话则没有什么影响//用在线工具转也可以,但最好用代码来进行转变,因为以后开发肯定是动态的一种方式最好//content ="\u5168\u56fd\u6211\u89c9\u5f97\u560e\u65af\u7684\u83b7\u5956\u60c5\u51b5\u5927\u624b\u7b14\u7684\u5427\u533a\u9694\u5316\u0061\u006b\u0073\u0068\u006c\u0064\u0065\u0071\u0077";for(int i =0 ; i < 4 ;i++){//gp.setColor(yanse[random.nextInt(3)]);设置填充的颜色随即化(为了验证码更复杂)char c =content.charAt(random.nextInt(content.length()));gp.drawString(c + "", 20 + 20*i, 30); //开始填充内容和位置}//如果想要验证码是数字的,则填充的内容为数字(生成四个数字)//for(int i=0 ; i<4 ;i++){//int number = random.nextInt(10);  //生成10以内的数字//gp.drawString(number + "", 20 + 20*i, 30); //开始填充内容和位置//}//设置不要缓存response.setHeader("Expires", -1+"");response.setHeader("Cache-control", "no-cache");response.setHeader("Pragma", "no-cache");//将验证码显示到对应的位置try {ImageIO.write(bi, "jpg", response.getOutputStream());} catch (IOException e) {e.printStackTrace();}}

 6:解决request提交的中文乱码问题

(1)当以Post方式进行提交时,只需要设置为

request.setCharacterEncoding("UTF-8");

            (2)当以Get方式进行提交时,则需要重建获取到的内容,比如表单提交了一个name过来,则

String name =request.getParameter("name");name = new String(name.getBytes("ISO-8859"),"UTF-8");

       当然,想想,如果填写中文的控件比较多,那么上面的方法就很麻烦了,所以就需要换一种方法。    
       这时候就需要更改一下服务器的内容配置了,就在端口号配置的Connector的地方,加上URIEncoding = “UTF-8”,这样就可以了。这主要就是
  就是改变服务器编码的方式来达到效果。

(3)当直接在地址栏中输入中文传送过来时,则需要如下进行处理了。
  比如地址为:http://localhost:8080/MyServletDemo/servlet/ChineseDemo1?username="我爱中国";
           这样的就需要如下处理:(注意这时候不需要更改服务器中的配置的encoding编码方式,对比一下情况(2))  

String name =request.getParameter("name");name = new String(name.getBytes("ISO-8859-1"));

 7:请求重定向的方法
           (1):使用 http头信息

response.setStatus(302);response.setHeader("location", request.getContexPath()+"/ServletDemo1");
 (2)使用response 对象中的sendRedirect()方法实现重定向
response.sendRedirect(request.getContexPath()+"/ServletDemo1");
        8:请求转发的方法       
RequestDispatcher rd = request.getRequestDispatcher("/ServletDemo1");rd.forward(request, response);
         请求重定向和请求转发的区别:
         重定向的时候地址栏会变化,而转发的时候地址栏是不会变化的.(请求重定向:两个请求;;;请求转发:一个请求)
9:请求包含的方法
RequestDispatcher rd = request.getRequestDispatcher("/ServletDemo1");rd.include(request, response);
请求包含和请求转发的区别:
作用其实差不多一样,但是在包含的意思就是相当于把转发的Servlet中的内容可以获取到,在前面的Servlet可以得到(转发也可以),但是他们的方向存在一定的差别
比如:在ServletDemo进行请求包含到ServletDemo2
在ServletDemo2中有,request.setAttribut("age","100");
这样的话,在ServletDemo1中就可以直接提前拿到了。
String userage = request.getAttribute("age");
        10:request对象的请求转发和ServletContext对象的请求转发的区别:
               request对象的支持相对路径,而ServletContext对象的不支持相对路径的写法。
  11:URL的写法(也就是到底什么时候需要加工程路径,什么时候不需要)
          (1)客户端都要写工程名称(request.getContextPath())
           比如:表单,超链,标签,img,link,script,请求重定向
(2)服务器端不需要加工程名
  比如:请求转发,请求包含
12:页面刷新
         (1)刷新当前页面(2秒后刷新) 
response.setHeader("Refresh","2");
(2)刷新到其他页面 
response.setHeader("Refresh","2;url=""/工程名+要刷新去的页面地址");
13:控制缓存的时间(这里时用10秒)
response.setDateHeader("Expiress",System.currentTimeMllis()+1000);

14:如何删除Cookie(官方是没有删除Cookie的这个API),所以就需要重新创建一个同名的,并设置存活时间为0,则可以

        Cookie c = new Cookie("要删除的Cookie的名字"," ");

        c.setMaxAge(0);

response.addCookie(c);

15:关于Img标签的src属性问题

      (1):访问Servlet(从Servlet中返回数据)比如:

<img alt="未知" src="http://localhost:8080/SendPictureToWeb/servlet/servletbackpicture">

     (2):访问WebContent的图片,比如

<img alt="未知" src="qwer.png">

     (3)访问Src目录下的图片,比如

  其中的path是在Servlet中获取;如String path = this.getServletContext().getRealPath("/WEB-INF/classes/qwer.png"); //下载gif或者图片

<img alt='图片缓存失败' src='"+path+"' border='10'  width='300' name='image' >

16:HTML页面读取从Servlet中获取本地图片进行显示

(方法一:在doPost方法中或者doGet方法中)

OutputStream out = response.getOutputStream();//读取本地图片输入流          FileInputStream inputStream = new FileInputStream(path);          int i = inputStream.available();          //byte数组用于存放图片字节数据          byte[] buff = new byte[i];          inputStream.read(buff);          //记得关闭输入流          inputStream.close();          //设置发送到客户端的响应内容类型          response.setContentType("image/*");           out.write(buff);          //关闭响应输出流          out.close(); 
(方法二:)

public class ImageShowServlet extends HttpServlet {        @Override      protected void service(HttpServletRequest request, HttpServletResponse response)              throws ServletException, IOException {          OutputStream os = response.getOutputStream();          File file = new File("C:\\abc.jpg");          FileInputStream fips = new FileInputStream(file);          byte[] btImg = readStream(fips);          os.write(btImg);          os.flush();      }            /**      * 读取管道中的流数据      */      public byte[] readStream(InputStream inStream) {          ByteArrayOutputStream bops = new ByteArrayOutputStream();          int data = -1;          try {              while((data = inStream.read()) != -1){                  bops.write(data);              }              return bops.toByteArray();          }catch(Exception e){              return null;          }      }  }  

17:创建唯一的值(用在Token 的生成中)

方法一:System,nanoTime() 方法

     Random rd = new Random();
String flag = System.nanoTime()+""+ rd.nextInt() ;     //理论上可能产生重复的,但实际不会

方法二:采用UUID类(采用128位的方式)

String flag = UUID.randomUUID().toString();

方法三:采用数据指纹的方式

String flag = UUID.randomUUID().toString();
//先进行MD5加密(还有SAH加密)
MessageDigest md = MessageDigest.getInstance("md5");
byte[] bs = flag.getBytes();
//采用数据指纹进一步加密
BASE64Encoder base = new BASE64Encoder();
String mima = base.encode(bs);  //得到最终的密文
解释一下上面的知识:其中的MD5加密就是一种加密算法,保密程度相对很高。所以这一步就很难破解了,另外讲一下关于BASE64Encoder这个类,其实这个类并不是JDK中自带的,而是Sun公司自己开发出来的,所以不能直接的引用到这个类,需要进行特殊处理,其中的步骤如下:

1:右击项目工程,点击Properties,

2:弹出一个框,然后点击Java Build Path,然后点击Libraries,点击Apache Tomacat (也就是默认的第一个)

3:这时候会看到Access rules这个,默认是显示着No rules defind,这时候点击一下,就显示Edit,进行添加规则。

4:又会弹出一个框,然后点击add,继续一个框,

5:在新的框中,第一个选项选择Accessible,第二个地方填入**(切记是这个符号,关于其他的可以参考那下面提示的一些其他的内容)

6:通过上面的方法,然后就可以引用了,记得是通过ctrl+shift+o(这是我默认的快捷键),注意不是ctrl+shift+f,这个普通的引用快捷,它们是有区别的

好了,再解释下关于BASE64Encoder这个类的具体方法,它其实做的就是将三字节扩充为四字节,,,,这样是不是破解难度又增加了呢?哈哈······

18:防止客户端重复提交数据(这个用在客户端进行注册的时候都能用到这个技术处理)

关键点:就是在客户端提交的时候,产生一个唯一的Token(这个在上面的一个问题中进行了方法的讲解),放入到Session中进行保存,并且在form表单中用一个<input type="hidden">进行存储这个token值,然后再提交后的界面进行读取。首先读取传送过来的参数的值,并且与session中的进行比较,如果相同,则表示是首次提交,这时候关键点,记住,当确认是首次提交后,需要将这个session里面的值进行删除。因为这样即使重新刷新当前页面,那么session里面就是空了,不会存在相等的情况,就表示不是首次提交,这样就能达到防止重复提交的功能。

19:Session默认的存活时间30分钟,这个可以在配置文件web.xml中进行修改的。比如:

<session-config>

<session-timeout>15</session-timeout>

<session-config>

好了,这次的就先记录到这里了,后面会继续出新的干货,,,,大家一起好好学习好好整理!!!!!!!!!!!!!</session-config>


       

 
原创粉丝点击