「aptjava编译」apt java
今天给各位分享aptjava编译的知识,其中也会对apt java进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
- 1、java调用webservice错误:Could not send Message
- 2、运行java程序说使用或覆盖了已过时的APT,使用-Xlint:deprecation重新编译怎么办啊
- 3、如何提供java的基于document/literal的webservice接口
- 4、java注解的类型可以是哪些
java调用webservice错误:Could not send Message
看ping通要连webServiceip或者浏览器访问址看能否现xml页面报错般网络通或端口问题。
java 调用webservice的各种方法:
利用jdk web服务api实现,这里使用基于 SOAP message 的 Web 服务
1、首先建立一个Web services EndPoint:
2、使用 apt 编译 Hello.java(例:apt -d [存放编译后的文件目录] Hello.java ) ,会生成 jaws目录
3、使用java Hello.Hello运行,然后将浏览器指向就会出现下列显示
4、使用wsimport 生成客户端
使用如下:wsimport -p . -keep
这时,会在当前目录中生成如下文件:
5、客户端程序:
运行java程序说使用或覆盖了已过时的APT,使用-Xlint:deprecation重新编译怎么办啊
这只是警告,运行时没问题的
原因是你使用了一些过时的API,这个警告只有在用5.0以上版本编译时才会有。
java 5.0 引入了 annotation ,
JDK帮助文档中明确说明:
用 @Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。从以下版本开始:1.5
辨别过时API方法:一是看API文档中是不是明确说了是已过时的,或者看JDK源代码中标注@Deprecated 的。
如果你使用Eclipse进行开发那就更简单了,当你使用过时的方法或类时,Eclipse会自动给该方法加上删除线,很显眼的。
这类方法只是不推荐使用,并不是不能使用,如果能找到更好的替代方法的话还是不用这类方法为好
另JDK API 的javadoc 官方下载地址(javaSE5.0):
;OrderID=QtFIBe.pkbcAAAElm2QdZ5sPProductID=EHbACUFBrJ8AAAEYWlA5AXuIFileName=/jdk-1_5_0-doc.zip
如何提供java的基于document/literal的webservice接口
一、利用jdk web服务api实现,这里使用基于SOAP message的Web服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
①.首先建立一个Web services EndPoint:package Hello;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.xml.ws.Endpoint;
@WebService
public class Hello {
@WebMethod
public String hello(String name) {
return "Hello, " + name + "\n";
}
public static void main(String[] args) {
// create and publish an endpoint
Hello hello = new Hello();
Endpoint endpoint = Endpoint.publish("
, hello);
}
}
②.使用apt编译Hello.java(例:apt -d [存放编译后的a href=";tn=44039180_cprfenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1Ydrj03PAnYmHw-m1IBnW6k0ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6KdThsqpZwYTjCEQLGCpyw9Uz4Bmy-bIi4WUvYETgN-TLwGUv3EnW0knW61PWR3nj6zPjbdP1n3r0" target="_blank" class="baidu-highlight"文件目录/a] Hello.java ) ,
会生成jaws目录
③.使用java Hello.Hello运行,然后将浏览器指向
就会出现下列显示
④.使用wsimport生成客户端使用如下:
wsimport -p . -keep
这时,会在a href=";tn=44039180_cprfenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1Ydrj03PAnYmHw-m1IBnW6k0ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6KdThsqpZwYTjCEQLGCpyw9Uz4Bmy-bIi4WUvYETgN-TLwGUv3EnW0knW61PWR3nj6zPjbdP1n3r0" target="_blank" class="baidu-highlight"当前目录/a中生成如下文件:
⑤.客户端程序:
1 class HelloClient{
2 public static void main(String args[]) {
3 HelloService service = new HelloService();
4 Hello helloProxy = service.getHelloPort();
5 String hello = helloProxy.hello("你好");
6 System.out.println(hello);
7 }
8 }
以上方法还稍显繁琐,还有更加简单的方法
二、使用xfire,我这里使用的是myeclipse集成的xfire进行测试的利用xfire开发WebService,可以有三种方法:
1. 一种是从javabean中生成;
2. 一种是从wsdl文件中生成;
3. 还有一种是自己建立webservice
步骤如下:
用myeclipse建立webservice工程,目录结构如下:首先建立webservice接口,
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1 package com.myeclipse.wsExample;
2 //Generated by MyEclipse
3
4 public interface IHelloWorldService {
5
6 public String example(String message);
7
8 }
接着实现这个借口:
1 package com.myeclipse.wsExample;
2 //Generated by MyEclipse
3
4 public class HelloWorldServiceImpl implements IHelloWorldService {
5
6 public String example(String message) {
7 return message;
8 }
9
10 }
修改 service.xml文件,加入以下代码:
1
2
3
4
5
6
7
8
9
10
11
12
1 service
2 nameHelloWorldService/name
3 serviceClass
4 com.myeclipse.wsExample.IHelloWorldService
5 /serviceClass
6 implementationClass
7 com.myeclipse.wsExample.HelloWorldServiceImpl
8 /implementationClass
9 stylewrapped/style
10 useliteral/use
11 scopeapplication/scope
12/service
把整个项目部署到tomcat服务器中打开浏览器,输入,可以看到如下:
然后再展开HelloWorldService后面的wsdl可以看到:
客户端实现如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
1 package com.myeclipse.wsExample.client;
2
3 import java.net.MalformedURLException;
4 import java.net.URL;
5
6 import org.codehaus.xfire.XFireFactory;
7 import org.codehaus.xfire.client.Client;
8 import org.codehaus.xfire.client.XFireProxyFactory;
9 import org.codehaus.xfire.service.Service;
10 import org.codehaus.xfire.service.binding.ObjectServiceFactory;
11
12 import com.myeclipse.wsExample.IHelloWorldService;
13
14 public class HelloWorldClient {
15 public static void main(String[] args) throws MalformedURLException, Exception {
16 // TODO Auto-generated method stub
17 Service s=new ObjectServiceFactory().create(IHelloWorldService.class);
18 XFireProxyFactory xf=new XFireProxyFactory(XFireFactory.newInstance().getXFire());
19 String url="
20
21 try
22 {
23
24 IHelloWorldService hs=(IHelloWorldService) xf.create(s,url);
25 String st=hs.example("zhangjin");
26 System.out.print(st);
27 }
28 catch(Exception e)
29 {
30 e.printStackTrace();
31 }
32 }
33
34 }
有时候我们知道一个wsdl地址,比如想用java客户端引用net做得webservice,使用myeclipse引用,但是却出现无法通过验证的错误,这时我们可以直接在类中引用,步骤如下:
1
2
1. public static void main(String[] args) throws MalformedURLException, Exception {
2. // TODO Auto-generated method stub
java注解的类型可以是哪些
使用注解
在一般的Java开发中,最常接触到的可能就是@Override和@SupressWarnings这两个注解了。使用@Override的时候只需要一个简单的声明即可。这种称为标记注解(marker annotation ),它的出现就代表了某种配置语义。而其它的注解是可以有自己的配置参数的。配置参数以名值对的方式出现。使用 @SupressWarnings的时候需要类似@SupressWarnings({"uncheck", "unused"})这样的语法。在括号里面的是该注解可供配置的值。由于这个注解只有一个配置参数,该参数的名称默认为value,并且可以省略。而花括号则表示是数组类型。在JPA中的@Table注解使用类似@Table(name = "Customer", schema = "APP")这样的语法。从这里可以看到名值对的用法。在使用注解时候的配置参数的值必须是编译时刻的常量。
从某种角度来说,可以把注解看成是一个XML元素,该元素可以有不同的预定义的属性。而属性的值是可以在声明该元素的时候自行指定的。在代码中使用注解,就相当于把一部分元数据从XML文件移到了代码本身之中,在一个地方管理和维护。
开发注解
在一般的开发中,只需要通过阅读相关的API文档来了解每个注解的配置参数的含义,并在代码中正确使用即可。在有些情况下,可能会需要开发自己的注解。这在库的开发中比较常见。注解的定义有点类似接口。下面的代码给出了一个简单的描述代码分工安排的注解。通过该注解可以在源代码中记录每个类或接口的分工和进度情况。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Assignment {
String assignee();
int effort();
double finished() default 0;
}
@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型。可以通过default来声明参数的默认值。在这里可以看到@Retention和@Target这样的元注解,用来声明注解本身的行为。@Retention用来声明注解的保留策略,有CLASS、RUNTIME和SOURCE这三种,分别表示注解保存在类文件、JVM运行时刻和源代码中。只有当声明为RUNTIME的时候,才能够在运行时刻通过反射API来获取到注解的信息。@Target用来声明注解可以被添加在哪些类型的元素上,如类型、方法和域等。
处理注解
在程序中添加的注解,可以在编译时刻或是运行时刻来进行处理。在编译时刻处理的时候,是分成多趟来进行的。如果在某趟处理中产生了新的Java源文件,那么就需要另外一趟处理来处理新生成的源文件。如此往复,直到没有新文件被生成为止。在完成处理之后,再对Java代码进行编译。JDK 5中提供了apt工具用来对注解进行处理。apt是一个命令行工具,与之配套的还有一套用来描述程序语义结构的Mirror API。Mirror API(com.sun.mirror.*)描述的是程序在编译时刻的静态结构。通过Mirror API可以获取到被注解的Java类型元素的信息,从而提供相应的处理逻辑。具体的处理工作交给apt工具来完成。编写注解处理器的核心是AnnotationProcessorFactory和AnnotationProcessor两个接口。后者表示的是注解处理器,而前者则是为某些注解类型创建注解处理器的工厂。
以上面的注解Assignment为例,当每个开发人员都在源代码中更新进度的话,就可以通过一个注解处理器来生成一个项目整体进度的报告。 首先是注解处理器工厂的实现。
public class AssignmentApf implements AnnotationProcessorFactory {
public AnnotationProcessor getProcessorFor(SetAnnotationTypeDeclaration atds,? AnnotationProcessorEnvironment env) {
if (atds.isEmpty()) {
return AnnotationProcessors.NO_OP;
}
return new AssignmentAp(env); //返回注解处理器
}
public CollectionString supportedAnnotationTypes() {
return Collections.unmodifiableList(Arrays.asList("annotation.Assignment"));
}
public CollectionString supportedOptions() {
return Collections.emptySet();
}
}
AnnotationProcessorFactory接口有三个方法:getProcessorFor是根据注解的类型来返回特定的注解处理器;supportedAnnotationTypes是返回该工厂生成的注解处理器所能支持的注解类型;supportedOptions用来表示所支持的附加选项。在运行apt命令行工具的时候,可以通过-A来传递额外的参数给注解处理器,如-Averbose=true。当工厂通过 supportedOptions方法声明了所能识别的附加选项之后,注解处理器就可以在运行时刻通过AnnotationProcessorEnvironment的getOptions方法获取到选项的实际值。注解处理器本身的基本实现如下所示。
public class AssignmentAp implements AnnotationProcessor {
private AnnotationProcessorEnvironment env;
private AnnotationTypeDeclaration assignmentDeclaration;
public AssignmentAp(AnnotationProcessorEnvironment env) {
this.env = env;
assignmentDeclaration = (AnnotationTypeDeclaration) env.getTypeDeclaration("annotation.Assignment");
}
public void process() {
CollectionDeclaration declarations = env.getDeclarationsAnnotatedWith(assignmentDeclaration);
for (Declaration declaration : declarations) {
processAssignmentAnnotations(declaration);
}
}
private void processAssignmentAnnotations(Declaration declaration) {
CollectionAnnotationMirror annotations = declaration.getAnnotationMirrors();
for (AnnotationMirror mirror : annotations) {
if (mirror.getAnnotationType().getDeclaration().equals(assignmentDeclaration)) {
MapAnnotationTypeElementDeclaration, AnnotationValue values = mirror.getElementValues();
String assignee = (String) getAnnotationValue(values, "assignee"); //获取注解的值
}
}
}
}
注解处理器的处理逻辑都在process方法中完成。通过一个声明(Declaration)的getAnnotationMirrors方法就可以获取到该声明上所添加的注解的实际值。得到这些值之后,处理起来就不难了。
在创建好注解处理器之后,就可以通过apt命令行工具来对源代码中的注解进行处理。 命令的运行格式是apt -classpath bin -factory annotation.apt.AssignmentApf src/annotation/work/*.java,即通过-factory来指定注解处理器工厂类的名称。实际上,apt工具在完成处理之后,会自动调用javac来编译处理完成后的源代码。
JDK 5中的apt工具的不足之处在于它是Oracle提供的私有实现。在JDK 6中,通过JSR 269把自定义注解处理器这一功能进行了规范化,有了新的javax.annotation.processing这个新的API。对Mirror API也进行了更新,形成了新的javax.lang.model包。注解处理器的使用也进行了简化,不需要再单独运行apt这样的命令行工具,Java编译器本身就可以完成对注解的处理。对于同样的功能,如果用JSR 269的做法,只需要一个类就可以了。
@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedAnnotationTypes("annotation.Assignment")
public class AssignmentProcess extends AbstractProcessor {
private TypeElement assignmentElement;
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
Elements elementUtils = processingEnv.getElementUtils();
assignmentElement = elementUtils.getTypeElement("annotation.Assignment");
}
public boolean process(Set? extends TypeElement annotations, RoundEnvironment roundEnv) {
Set? extends Element elements = roundEnv.getElementsAnnotatedWith(assignmentElement);
for (Element element : elements) {
processAssignment(element);
}
}
private void processAssignment(Element element) {
List? extends AnnotationMirror annotations = element.getAnnotationMirrors();
for (AnnotationMirror mirror : annotations) {
if (mirror.getAnnotationType().asElement().equals(assignmentElement)) {
Map? extends ExecutableElement, ? extends AnnotationValue values = mirror.getElementValues();
String assignee = (String) getAnnotationValue(values, "assignee"); //获取注解的值
}
}
}
}
仔细比较上面两段代码,可以发现它们的基本结构是类似的。不同之处在于JDK 6中通过元注解@SupportedAnnotationTypes来声明所支持的注解类型。另外描述程序静态结构的javax.lang.model包使用了不同的类型名称。使用的时候也更加简单,只需要通过javac -processor annotation.pap.AssignmentProcess Demo1.java这样的方式即可。
上面介绍的这两种做法都是在编译时刻进行处理的。而有些时候则需要在运行时刻来完成对注解的处理。这个时候就需要用到Java的反射API。反射API提供了在运行时刻读取注解信息的支持。不过前提是注解的保留策略声明的是运行时。Java反射API的AnnotatedElement接口提供了获取类、方法和域上的注解的实用方法。比如获取到一个Class类对象之后,通过getAnnotation方法就可以获取到该类上添加的指定注解类型的注解。
实例分析
下面通过一个具体的实例来分析说明在实践中如何来使用和处理注解。假定有一个公司的雇员信息系统,从访问控制的角度出发,对雇员的工资的更新只能由具有特定角色的用户才能完成。考虑到访问控制需求的普遍性,可以定义一个注解来让开发人员方便的在代码中声明访问控制权限。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequiredRoles {
String[] value();
}
下一步则是如何对注解进行处理,这里使用的Java的反射API并结合动态代理。下面是动态代理中的InvocationHandler接口的实现。
public class AccessInvocationHandlerT implements InvocationHandler {
final T accessObj;
public AccessInvocationHandler(T accessObj) {
this.accessObj = accessObj;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
RequiredRoles annotation = method.getAnnotation(RequiredRoles.class); //通过反射API获取注解
if (annotation != null) {
String[] roles = annotation.value();
String role = AccessControl.getCurrentRole();
if (!Arrays.asList(roles).contains(role)) {
throw new AccessControlException("The user is not allowed to invoke this method.");
}
}
return method.invoke(accessObj, args);
}
}
在具体使用的时候,首先要通过Proxy.newProxyInstance方法创建一个EmployeeGateway的接口的代理类,使用该代理类来完成实际的操作。
aptjava编译的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于apt java、aptjava编译的信息别忘了在本站进行查找喔。