Live2d Test Env

注解

注解的基本知识:

1.示列

@Deprecated :标注XX过时

@SuppressWarning:抑制警告:unused:抑制的警告类型{ "unused", "rawtypes", "unchecked" }:数组,抑制的多个警告类型;all:抑制所有警告

@Override:保证用户确实是覆盖了父类的某个方法。

2.自定义注解

使用@interface关键字来声明注解;public @interface MyAnn1{};声明注解的属性字段:类型   字段名()[defalut  默认值];

注解的类型只能是下面的几个:String     Class     八个类型     注解类型     枚举类型     及以上类型的1维数组;

特殊属性:String    value;或者String[]  value();   使用时候直接给定取值,而不用加属性名称;

3.元注解

服务于注解的注解就是元注解

@Retention:指定注解的存活范围。默认是CLASS

RetentionPolicy:SOURCE|CLASS|RUNTIME

 

@Target:指定注解可以用在什么元素上

ElementType:TYPE|METHOD|。。。

 1 import java.lang.annotation.ElementType;
 2 import java.lang.annotation.Retention;
 3 import java.lang.annotation.RetentionPolicy;
 4 import java.lang.annotation.Target;
 5 
 6 @Retention(RetentionPolicy.RUNTIME)
 7 @Target(ElementType.METHOD)
 8 public @interface MyTest {
 9     long time() default -1;
10 }
@Retention@Target

@Documented: 用于指定被该元 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档.

@Inherited: 被它修饰的 Annotation 将具有继承性.如果某个类使用了被 @Inherited 修饰的 Annotation, 则其子类将自动具有该注解

注解的反射

 1 import java.lang.reflect.InvocationTargetException;
 2 import java.lang.reflect.Method;
 3 
 4 //反射注解:所有注解类型都是Annotation类型的子类
 5 /*
 6 java.lang.reflect.AnnotatedElement:
 7     <T extends Annotation> getAnnotation(Class<T> annotationType):
 8         获取指定类型的注解
 9     Annotation[] getAnnotations():获取所有的注解
10     Annotation[] getDeclareAnnotations():返回直接存在于此元素上的所有注释
11     boolean isAnnotationPresend(Class<? extends Annotation>):有木有指定的注解
12     
13     Class, Constructor, Field, Method, Package都实现了该接口
14  */
15 public class MyTestRunner {
16     //执行测试:
17     /*
18      * 获取要测试的java类:MyJunitTest
19      * 取到其中的所有方法:Method
20      * 看看谁的方法前面有@MyTest的注解,谁有就执行谁
21      */
22     public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {
23         test2();
24     }
25     //反射带有属性的注解
26     private static void test2() throws IllegalAccessException,
27             InvocationTargetException, InstantiationException {
28         Class clazz = MyJunitTest.class;
29         Method ms[] = clazz.getMethods();
30         for(Method m:ms){
31             MyTest myTest = m.getAnnotation(MyTest.class);
32             if(myTest!=null){
33                 //得到注解的属性
34                 long timeLimit = myTest.time();
35                 if(timeLimit>-1){
36                     //有性能测试需求
37                     long startTime = System.nanoTime();
38                     m.invoke(clazz.newInstance(), null);
39                     long useTime = System.nanoTime()-startTime;
40                     if(useTime>timeLimit){
41                         System.out.println(m.getName()+"执行效率没有测试通过");
42                     }
43                 }else{
44                     //没有性能测试需求
45                     m.invoke(clazz.newInstance(), null);
46                 }
47                 
48             }
49         }
50     }
51     //注解的基本反射
52     private static void test1() throws IllegalAccessException,
53             InvocationTargetException, InstantiationException {
54         Class clazz = MyJunitTest.class;
55         Method ms[] = clazz.getMethods();
56         for(Method m:ms){
57             boolean b = m.isAnnotationPresent(MyTest.class);
58 //            System.out.println(m.getName()+"方法上有木有MyTest注解:"+b);
59             if(b){
60                 m.invoke(clazz.newInstance(), null);
61             }
62         }
63     }
64 
65 }
MyTestRunner

1. 指定运行时生命周期才能进行测试

 2.指定在指定时间内执行完,才算是测试成功

注解

替换传统的XML配置文件。 

比如:映射一个Servlet

------------------ 

public class MyServlet extends HttpServlet{

... 

}
View Code

web.xml

<servlet>

 

<servlet-name>MyServlet</servlet-name>

 

<servlet-class>com.itheima.MyServlet</servlet-class>

 

</servlet>

 

<servlet-mapping>

 

<servlet-name>MyServlet</servlet-name>

 

<url-pattern>/servlet/MyServlet</url-pattern>

 

</servlet-mapping>

 

--------------------------------------------------------------

 
View Code
@WebServlet(urlPattern=”/servlet/MyServlet”)
public class MyServlet extends HttpServlet{}

 Servlet3.0的新特征 

JavaEE5.0:Servlet2.5

JavaEE6.0:Servlet3.0

1、前提:

Tomcat7.X   JDK6.X

2、Servlet3.0比Servlet2.5多了哪些功能

1.不用配置xml文件的设置,用注解

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns="/servlet/ServletDemo1",initParams=@WebInitParam(name="encoding",value="ANNVAUE"))

//注册配置的和web.xml配置的都会实例化一次
//建议:要么用注解,要么用web.xml
public class ServletDemo extends HttpServlet {
    public void init() throws ServletException {
        System.out.println("初始化了");
    }
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println(this);
        System.out.println("ServletDemo1执行了");
        String value = getServletConfig().getInitParameter("encoding");
        System.out.println(value);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

ServletDemo1
ServletDemo.java

2.文件上传的改变

2.1:上传形式不变:

      

2.2:

import java.io.IOException;
import java.util.Collection;
import java.util.Collections;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
@WebServlet("/servlet/UploadServlet")
@MultipartConfig //告知处理的是multipart/form-data类型的数据
public class UploadServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
//        Collection<Part> parts = request.getParts();
//        for(Part p:parts)
//            System.out.println(p);
        
        //传统方式获取参数能用了
//        String name = request.getParameter("name");
//        System.out.println(name);
        
        //处理文件上传
        Part part = request.getPart("photo");
        //获取上传文件的文件名
        String headerValue = part.getHeader("Content-Disposition");//  form-data; name="photo"; filename="AOP.txt"
        int index = headerValue.indexOf("filename=");
        String filename = headerValue.substring(index+10, headerValue.length()-1);
        part.write(getServletContext().getRealPath("/files")+"/"+filename);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

UploadServlet
UploadServlet.java

3.web片段:

注解的引入使得web.xml变成可选的了。但是,我们还是可以使用web.xml。容器会根据web.xml中的metadata- complete元素的值来决定使用web.xml还是使用注解。如果该元素的值是true,那么容器不处理注解,web.xml是所有信息的来源。如果 该元素不存在或者其值不为true,容器才会处理注解。

Web框架的可插入性

我们前面说过了Servlet3.0的改进之一就是使得我们能够将框架和库插入到web应用程序中。这种可插入性减少了配置,并且提高了web应用程序的模块化。Servlet3.0是通过web模块布署描述片段(简称web片段)来实现插入性的。
一个web片段就是web.xml文件的一部分,被包含在框架特定的Jar包的META-INF目录中。Web片段使得该框架组件逻辑上就是web应用程序的一部分,不需要编辑web布署描述文件。
Web 片段中使用的元素和布署文件中使用的元素基本相同,除了根元素不一样。Web片段的根元素是<web-fragment>,而且文件名必须叫 做web-fragment.xml。容器只会在放在WEB-INF\lib目录下的Jar包中查找web-fragment.xml文件。如果这些 Jar包含有web-fragment.xml文件,容器就会装载需要的类来处理他们。
在web.xml中,我们要求Servlet的name必须唯一。同样的,在web.xml和所有的web片段中,Servlet的name也必须唯一。
下面就是一个web-fragment的例子:

<web-fragment>
<servlet>
<servlet-name>ControllerServlet</servlet-name>
<servlet-class>com.app.control.ControllerServlet</servlet-class>
</servlet>
<listener> <listener-class>com.listener.AppServletContextListener</listener-class>
</listener>

框架的Jar包是放在WEB-INF\lib目录下的,但是Servlet3.0提供两种方法指定多个web片段之间的顺序:
   1. 绝对顺序
   2. 相对顺序
我 们通过web.xml文件中的<absolute-ordering>元素来指定绝对顺序。这个元素有之元素name,name的值是各个 web片段的name元素的值。这样就指定了web片段的顺序。如果多个web片段有相同的名字,容器会忽略后出现的web片段。下面是一个指定绝对顺序 的例子:

 <web-app>
<name>DemoApp</name>
<absolute-ordering>
<name>WebFragment1</name>
<name>WebFragment2</name>
</absolute-ordering>
 </web-app>

相对顺序通过web-fragment.xml中的<ordering>元素来确定。Web片段的顺序 由<ordering>的子元素<before>,<after>和<others>来决定。当前的 web片段会放在所有的<before>元素中的片段之前。同样的,会放在所有的<after>元素中的片段之 后。<others>用来代替所有的其他片段。注意只有当web.xml中没有<absolute-ordering>时,容器 才会使用web片段中定义的相对顺序。
下面是一个帮助理解相对顺序的例子:

<web-fragment>
<name>WebFragment1</name>
<ordering><after>WebFragment2</after></ordering>
</web-fragment>

 

<web-fragment>
<name>WebFragment2</name>
</web-fragment>

 

<web-fragment>
<name>WebFragment3</name>
<ordering><before><others/></before></ordering>
</web-fragment>

这些文件将会按照下面的顺序被处理:

   1. WebFragment3
   2. WebFragment2
   3. WebFragment1

包含WebFragment3的Jar文件被最先处理,包含WebFragment2的文件被第二个处理,包含WebFragment1的文件被最后处理。
如果既没有定义绝对顺序,也没有定义相对顺序,那么容器就认为所有的web片段间没有顺序上的依赖关系。

4.同步和异步:

同步:

同步的思想是:所有的操作都做完,才返回给用户。这样用户在线等待的时间太长,给用户一种卡死了的感觉(就是系统迁移中,点击了迁移,界面就不动了,但是程序还在执行,卡死了的感觉)。这种情况下,用户不能关闭界面,如果关闭了,即迁移程序就中断了。

异步:

将用户请求放入消息队列,并反馈给用户,系统迁移程序已经启动,你可以关闭浏览器了。然后程序再慢慢地去写入数据库去。这就是异步。但是用户没有卡死的感觉,会告诉你,你的请求系统已经响应了。你可以关闭界面了。

同步,是所有的操作都做完,才返回给用户结果。即写完数据库之后,在相应用户,用户体验不好。

异步,不用等所有操作等做完,就相应用户请求。即先相应用户请求,然后慢慢去写数据库,用户体验较好。

异步操作例子:

为了避免短时间大量的数据库操作,就使用缓存机制,也就是消息队列。先将数据放入消息队列,然后再慢慢写入数据库。

引入消息队列机制,虽然可以保证用户请求的快速响应,但是并没有使得我数据迁移的时间变短(即80万条数据写入mysql需要1个小时,用了redis之后,还是需要1个小时,只是保证用户的请求的快速响应。用户输入完http url请求之后,就可以把浏览器关闭了,干别的去了。如果不用redis,浏览器不能关闭)。

同步就没有任何价值了吗?银行的转账功能。

 

 

 

 1 import java.io.IOException;
 2 import java.io.PrintWriter;
 3 
 4 import javax.servlet.AsyncContext;
 5 import javax.servlet.ServletException;
 6 import javax.servlet.annotation.WebServlet;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 @WebServlet(urlPatterns="/RegistServlet",asyncSupported=true)
11 public class RegistServlet extends HttpServlet {
12 
13     public void doGet(HttpServletRequest request, HttpServletResponse response)
14             throws ServletException, IOException {
15         response.setContentType("text/html;charset=UTF-8");
16         PrintWriter out = response.getWriter();
17         out.write("RegistServlet开始运行了<br/>");
18         out.flush();
19         try {
20             Thread.sleep(2000);
21         } catch (InterruptedException e) {
22             e.printStackTrace();
23         }
24         out.write("注册成功了<br/>");
25         out.flush();
26         //发送激活邮件
27         AsyncContext ac = request.startAsync();//开始异步
28         new Thread(new SendMail(ac)).start();//3秒
29         out.write("RegistServlet运行结束了<br/>");
30         out.flush();
31     }
32 
33     public void doPost(HttpServletRequest request, HttpServletResponse response)
34             throws ServletException, IOException {
35         doGet(request, response);
36     }
37 
38 }
39 class SendMail implements Runnable{
40 
41     private AsyncContext ac;
42 
43     public SendMail(AsyncContext ac) {
44         this.ac= ac;
45     }
46 
47     public void run() {
48         try {
49             Thread.sleep(3000);
50         } catch (InterruptedException e) {
51             e.printStackTrace();
52         }
53         //打印信息
54         try {
55             PrintWriter out = ac.getResponse().getWriter();
56             out.write("邮件发送成功!");
57             out.flush();
58         } catch (IOException e) {
59             e.printStackTrace();
60         }
61     }
62     
63 }
RegistServlet.java

 

posted @ 2018-07-23 00:21  麦奇  阅读(294)  评论(0编辑  收藏  举报