2017-01-25 4 views
0

В соответствии с ValidationFeature documentation для того, чтобы проверки произойдет операций ввода и вывода привязки должны быть аннотированный с @ValidCXF-CodeGen-плагин не соответствует CXF ValidationFeature

Однако интерфейс Webservice генерируемого CXF-codegen- плагин не имеет этих аннотаций, и я, кажется, не нашел аргумент командной строки или плагин, который позволяет их добавлять.

В @Valid аннотация не может быть поставлена ​​в реализации интерфейса Webservice, не нарушая принцип замещения Лиск: ссылка реализация JSR-349 (Hibernate Validator) в этом случае производит HV000151: Метод переопределяя другой метод не должен изменять параметр ограничения конфигурации

Вопрос: ли кто-нибудь известно о пути к аннотировать CXF генерируемых веб-сервиса параметры метода интерфейса с @Valid?

Я знаю о существовании Annox plugin, но это, как представляется, не является легкой задачей для достижения этой цели. Самым простым решением можно было бы вручную добавить @Valid аннотацию к интерфейсу WebService, но я не комфортно в модифицирующих сгенерированный код

продукта примера

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>org.example.www</groupId> 
    <artifactId>webservice-test-bval</artifactId> 
    <version>1.0.0-SNAPSHOT</version> 
    <packaging>war</packaging> 
    <name>Test bean validation on web service</name> 

    <properties> 
     <org.springframework.boot.version>1.4.2.RELEASE</org.springframework.boot.version> 
     <com.github.krasa.krasa-jaxb-tools>1.5</com.github.krasa.krasa-jaxb-tools> 
     <org.apache.cxf.version>3.1.3</org.apache.cxf.version> 
     <cxf-codegen-plugin.version>3.0.1</cxf-codegen-plugin.version> 
    </properties> 


    <dependencyManagement> 
     <dependencies> 
      <dependency> 
       <!-- Import dependency management from Spring Boot --> 
       <groupId>org.springframework.boot</groupId> 
       <artifactId>spring-boot-dependencies</artifactId> 
       <version>${org.springframework.boot.version}</version> 
       <type>pom</type> 
       <scope>import</scope> 
      </dependency> 
     </dependencies> 
    </dependencyManagement> 


    <dependencies> 
     <!-- Spring boot dependencies --> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-web</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-tomcat</artifactId> 
      <scope>provided</scope> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-test</artifactId> 
      <scope>test</scope> 
     </dependency> 


     <!-- CXF dependencies --> 
     <dependency> 
      <groupId>org.apache.cxf</groupId> 
      <artifactId>cxf-rt-frontend-jaxws</artifactId> 
      <version>${org.apache.cxf.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.apache.cxf</groupId> 
      <artifactId>cxf-rt-transports-http</artifactId> 
      <version>${org.apache.cxf.version}</version> 
     </dependency> 
     <!-- Schema validation --> 
     <dependency> 
      <groupId>com.github.krasa</groupId> 
      <artifactId>krasa-jaxb-tools</artifactId> 
      <version>${com.github.krasa.krasa-jaxb-tools}</version> 
      <exclusions> 
       <exclusion> 
        <groupId>javax.validation</groupId> 
        <artifactId>validation-api</artifactId> 
       </exclusion> 
      </exclusions> 
     </dependency> 
     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-validator</artifactId> 
     </dependency> 
    </dependencies> 

    <build> 
     <finalName>${project.artifactId}</finalName> 
     <plugins> 

      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <version>3.1</version> 
       <configuration> 
        <source>1.8</source> 
        <target>1.8</target> 
       </configuration> 
      </plugin> 
      <plugin> 
       <groupId>org.springframework.boot</groupId> 
       <artifactId>spring-boot-maven-plugin</artifactId> 
       <version>${org.springframework.boot.version}</version> 
      </plugin> 

      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-war-plugin</artifactId> 
       <configuration> 
        <failOnMissingWebXml>false</failOnMissingWebXml> 
       </configuration> 
      </plugin> 

      <plugin> 
       <groupId>org.apache.cxf</groupId> 
       <artifactId>cxf-codegen-plugin</artifactId> 
       <version>${cxf-codegen-plugin.version}</version> 
       <executions> 
        <execution> 
         <id>generate-sources</id> 
         <phase>generate-sources</phase> 
         <configuration> 
          <sourceRoot>${project.build.directory}/generated/</sourceRoot> 
          <wsdlOptions> 
           <wsdlOption> 
            <wsdl>${project.basedir}/src/main/resources/wsdl/test.wsdl</wsdl> 
            <wsdlLocation>classpath:wsdl/test.wsdl</wsdlLocation> 
            <extraargs> 
             <extraarg>-xjc-XJsr303Annotations</extraarg> 
            </extraargs> 
           </wsdlOption> 
          </wsdlOptions> 
         </configuration> 
         <goals> 
          <goal>wsdl2java</goal> 
         </goals> 
        </execution> 
       </executions> 
       <dependencies> 
        <dependency> 
         <groupId>com.github.krasa</groupId> 
         <artifactId>krasa-jaxb-tools</artifactId> 
         <version>${com.github.krasa.krasa-jaxb-tools}</version> 
        </dependency> 
       </dependencies> 
      </plugin> 
     </plugins> 
    </build> 
</project> 

SRC/main/resources/wsdl/

test.wsdl

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.example.org/test/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    name="test" targetNamespace="http://www.example.org/test/"> 
    <wsdl:types> 
     <xsd:schema targetNamespace="http://www.example.org/test/"> 
      <xsd:element name="NewOperation"> 
       <xsd:complexType> 
        <xsd:sequence> 
         <xsd:element name="in"> 
          <xsd:simpleType> 
           <xsd:restriction base="xsd:int"> 
            <xsd:minInclusive value="10" /> 
            <xsd:maxInclusive value="20" /> 
           </xsd:restriction> 
          </xsd:simpleType> 
         </xsd:element> 
        </xsd:sequence> 
       </xsd:complexType> 
      </xsd:element> 
      <xsd:element name="NewOperationResponse"> 
       <xsd:complexType> 
        <xsd:sequence> 
         <xsd:element name="out"> 
          <xsd:simpleType> 
           <xsd:restriction base="xsd:string"> 
            <xsd:pattern value="[A-Z]+" /> 
           </xsd:restriction> 
          </xsd:simpleType> 
         </xsd:element> 
        </xsd:sequence> 
       </xsd:complexType> 
      </xsd:element> 
     </xsd:schema> 
    </wsdl:types> 
    <wsdl:message name="NewOperationRequest"> 
     <wsdl:part element="tns:NewOperation" name="parameters" /> 
    </wsdl:message> 
    <wsdl:message name="NewOperationResponse"> 
     <wsdl:part element="tns:NewOperationResponse" name="parameters" /> 
    </wsdl:message> 
    <wsdl:portType name="testWS"> 
     <jaxws:bindings xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"> 
      <jaxws:enableWrapperStyle>false</jaxws:enableWrapperStyle> 
     </jaxws:bindings> 
     <wsdl:operation name="NewOperation"> 
      <wsdl:input message="tns:NewOperationRequest" /> 
      <wsdl:output message="tns:NewOperationResponse" /> 
     </wsdl:operation> 
    </wsdl:portType> 
    <wsdl:binding name="testWSSOAP" type="tns:testWS"> 
     <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> 
     <wsdl:operation name="NewOperation"> 
      <soap:operation soapAction="http://www.example.org/test/NewOperation" /> 
      <wsdl:input> 
       <soap:body use="literal" /> 
      </wsdl:input> 
      <wsdl:output> 
       <soap:body use="literal" /> 
      </wsdl:output> 
     </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:service name="testWS"> 
     <wsdl:port binding="tns:testWSSOAP" name="testWSSOAP"> 
      <soap:address location="http://www.example.org/" /> 
     </wsdl:port> 
    </wsdl:service> 
</wsdl:definitions> 

SRC/Основной/Java/

org.example.test

package org.example.test; 

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.boot.web.support.SpringBootServletInitializer; 

@SpringBootApplication 
public class Application extends SpringBootServletInitializer { 

    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 
} 

package org.example.test; 

import javax.jws.WebMethod; 
import javax.jws.WebParam; 
import javax.jws.WebResult; 
import javax.jws.WebService; 
import javax.jws.soap.SOAPBinding; 
import javax.validation.Valid; 
import javax.xml.bind.annotation.XmlSeeAlso; 
import javax.xml.ws.RequestWrapper; 
import javax.xml.ws.ResponseWrapper; 

import org.example.test.ObjectFactory; 

@WebService(targetNamespace = "http://www.example.org/test/", name = "testWS") 
@XmlSeeAlso({ObjectFactory.class}) 
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE) 
public interface TestWSValid { 

    @WebMethod(operationName = "NewOperation", action = "http://www.example.org/test/NewOperation") 
    @Valid @WebResult(name = "NewOperationResponse", targetNamespace = "http://www.example.org/test/", partName = "parameters") 
    public NewOperationResponse newOperation(
      @Valid @WebParam(partName = "parameters", name = "NewOperation", targetNamespace = "http://www.example.org/test/") 
     NewOperation parameters 
    ); 
} 

org.example.test.configuration

package org.example.test.configuration; 

import javax.xml.ws.Endpoint; 

import org.apache.cxf.Bus; 
import org.apache.cxf.feature.Feature; 
import org.apache.cxf.jaxws.EndpointImpl; 
import org.apache.cxf.transport.servlet.CXFServlet; 
import org.apache.cxf.validation.BeanValidationFeature; 
import org.example.test.services.TestWSImpl; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.web.servlet.ServletRegistrationBean; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.ImportResource; 

@Configuration 
@ImportResource({ "classpath:META-INF/cxf/cxf.xml", "classpath:META-INF/cxf/cxf-servlet.xml" }) 
@ComponentScan({ "org.example.test" }) 
public class ApplicationConfiguration { 

    @Autowired 
    private Bus cxfBus; 

    @Bean 
    public Endpoint testWSEndpoint() { 
     EndpointImpl endpoint = new EndpointImpl(cxfBus, new TestWSImpl()); 
     endpoint.setAddress("/testws"); 
     endpoint.publish(); 
     return endpoint; 
    } 

    @Bean 
    public ServletRegistrationBean cxfServlet() { 
     ServletRegistrationBean servlet = new ServletRegistrationBean(new CXFServlet(), "/services/*"); 
     servlet.setLoadOnStartup(1); 
     return servlet; 
    } 

    @Bean 
    public Feature validationFeature() { 
     Feature validationFeature = new BeanValidationFeature(); 
     validationFeature.initialize(cxfBus); 
     cxfBus.getFeatures().add(validationFeature); 
     ConstraintViolationInterceptor interceptor = new ConstraintViolationInterceptor(); 
     cxfBus.getInFaultInterceptors().add(interceptor); 
     cxfBus.getOutFaultInterceptors().add(interceptor); 
     cxfBus.getProperties().put("exceptionMessageCauseEnabled", true); 
     return validationFeature; 
    } 
} 

package org.example.test.configuration; 

import java.text.MessageFormat; 
import java.util.stream.Collectors; 

import javax.validation.ConstraintViolationException; 

import org.apache.cxf.binding.soap.SoapMessage; 
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor; 
import org.apache.cxf.binding.soap.interceptor.Soap11FaultOutInterceptor; 
import org.apache.cxf.interceptor.Fault; 
import org.apache.cxf.phase.Phase; 

public class ConstraintViolationInterceptor extends AbstractSoapInterceptor { 

    public ConstraintViolationInterceptor() { 
     super(Phase.MARSHAL); 
     getBefore().add(Soap11FaultOutInterceptor.class.getName()); 
    } 

    private static final String TEMPLATE = "[{0}] {1} : {2}"; 

    @Override 
    public void handleMessage(SoapMessage message) throws Fault { 
     Fault fault = (Fault) message.getContent(Exception.class); 
     Throwable exception = fault.getCause(); 
     if (exception instanceof ConstraintViolationException) { 
      fault.setMessage(processConstraints((ConstraintViolationException) exception)); 
     } 
    } 

    private String processConstraints(ConstraintViolationException exception) { 
     return exception.getConstraintViolations().stream().map((error) -> { 
      return MessageFormat.format(TEMPLATE, error.getPropertyPath(), error.getMessage(), error.getInvalidValue()); 
     }).collect(Collectors.joining(System.lineSeparator())); 
    } 

} 

org.example.test. услуги

package org.example.test.services; 

import javax.jws.WebService; 

import org.example.test.NewOperation; 
import org.example.test.NewOperationResponse; 
import org.example.test.ObjectFactory; 
import org.example.test.TestWS; 

@WebService(endpointInterface = "org.example.test.TestWS", portName = "TestWSPort", serviceName = "TestWS", targetNamespace = "http://www.example.org/test/") 
public class TestWSImpl implements TestWS { 

    @Override 
    public NewOperationResponse newOperation(NewOperation parameters) { 
     int in = parameters.getIn(); 
     NewOperationResponse response = new ObjectFactory().createNewOperationResponse(); 
     if (in < 10 || in > 20) { 
      response.setOut("no no no"); 
     } else { 
      response.setOut("OK"); 
     } 
     return response; 
    } 

} 

Со ссылкой на вышеназванном проект, вы можете проверить, что до тех пор, как TestWSImpl implements TestWS (сгенерированный класс) не существует никакой проверки встречающейся, но если TestWSImpl implements TestWSValid (класс, который содержит сгенерированный код с @Valid дополнения), то проверки работа как ожидалось

ответ

0

Поддержка wsdl2java Apache CXF является подключаемой. Существует описатель META-INF/tools-plugin.xml, который позволяет вам определять пользовательские генераторы («frontend profiles»). Поэтому, если вам нужна аннотация @Valid на всех интерфейсах webservice, созданных cxf, вы можете просто подключить пользовательский SEIGenerator. Apache CXF использует шаблоны Velocity для генерации интерфейсов SEI. Поэтому вам просто нужно перезаписать шаблон по умолчанию с помощью настраиваемого.

Так что вместо использования Anox или Krasa вы можете просто создать простую перезапись cxf-codegen-plugin.

Так что давайте создадим отдельный проект, но вы можете поместить его в один и тот же проект, но в другом модуле, но для лучшего повторного использования я бы сказал, что новый проект.

pom.xml

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 

    <groupId>org.example.test</groupId> 
    <artifactId>valid-cxf</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <modelVersion>4.0.0</modelVersion> 

    <dependencies> 
     <dependency> 
      <groupId>org.apache.cxf</groupId> 
      <artifactId>cxf-codegen-plugin</artifactId> 
      <version>${org.apache.cxf.version}</version> 
     </dependency> 
    </dependencies> 

</project> 

Позволяет загрузчик службы использовать для определения нового генератора по умолчанию SEI.

SRC/главная/ресурсы/META-INF/инструменты-plugin.xml

<?xml version="1.0" encoding="utf-8"?> 
<plugin xmlns="http://cxf.apache.org/tools/plugin" name="play" version="" provider="play.typesafe.com"> 
    <frontend name="sample" package="org.apache.cxf.tools.wsdlto.frontend.jaxws" profile="JAXWSProfile"> 
    <container name="JAXWSContainer" package="org.apache.cxf.tools.wsdlto.frontend.jaxws" toolspec="jaxws-toolspec.xml"/> 
    <processor name="WSDLToJavaProcessor" package="org.apache.cxf.tools.wsdlto.frontend.jaxws.processor"/> 
    <builder name="JAXWSDefinitionBuilder" package="org.apache.cxf.tools.wsdlto.frontend.jaxws.wsdl11"/> 
    <generators package="com.example.plugin"> 
     <generator name="CustomSEIGenerator"/> 
    </generators> 
</frontend> 

Здесь мы определили новый SEIGenerator с именем CustomSEIGenerator из пакета com.example.plugin

Далее дается определение шаблона скорости со всеми нашими перезаписываемыми (в нашем случае только жесткокодированные @Valid аннотация по интерфейсу веб-сервиса). Этот метод основан на официального CxF sei.vm

SRC/основные/ресурсы/Правильный-sei.vm

#if ($intf.packageJavaDoc != "") 
/** 
$intf.packageJavaDoc 
*/ 
#end 
package $intf.PackageName; 

#if ($mark-generated == "true") 
import javax.annotation.Generated; 
#end 
import javax.validation.Valid; 
#foreach ($import in $intf.Imports) 
import ${import}; 
#end 

/** 
#if ($intf.classJavaDoc != "") 
$intf.classJavaDoc 
* 
#end 
* This class was generated by $fullversion 
* $currentdate 
* Generated source version: $version 
* 
*/ 
#foreach ($annotation in $intf.Annotations) 
$annotation 
#end 
#if ($mark-generated == "true") 
@Generated(value = "org.apache.cxf.tools.wsdlto.WSDLToJava", date =  "$currentdate", comments = "$fullversion") 
#end 
public interface $intf.Name ${sei-superinterface-string}{ 
#foreach ($method in $intf.Methods) 

#if ($method.JavaDoc != "") 
    /** 
${method.JavaDoc} 
    */ 
#end 
#foreach ($annotation in $method.Annotations) 
    $annotation 
#end 
@Valid 
#if ($mark-generated == "true") 
    @Generated(value = "org.apache.cxf.tools.wsdlto.WSDLToJava", date = "$currentdate") 
#end 
    public $method.returnValue ${method.Name}(#if($method.ParameterList.size() == 0))#end 
#if($method.ParameterList.size() != 0) 

#foreach ($param in ${method.ParameterList}) 
    $param 
#end 
)#end#if($method.Exceptions.size() > 0) throws#foreach($exception in $method.Exceptions) $exception.ClassName#if($method.Exceptions.size() != $velocityCount),#end#end#end; 
#end 
} 

И в конце позволяет создать CustomSEIGenerator, который будет использовать наш шаблон скорости.

package org.example.test; 

import org.apache.cxf.tools.common.ToolException; 
import org.apache.cxf.tools.wsdlto.frontend.jaxws.generators.SEIGenerator; 

import java.io.Writer; 

/** 
* Just a sample custom generator which use custom velocity template to generate SEI 
* 
*/ 
public class CustomSEIGenerator extends SEIGenerator { 

    @Override 
    protected void doWrite(String templateName, Writer outputs) throws ToolException { 

     if (templateName.endsWith("/sei.vm")) { 
      templateName = "valid-sei.vm"; 
     } 

     super.doWrite(templateName, outputs); 
    } 
} 

Если у вас есть построить плагин перезапись и опубликованы на локальном Maven репо, рядом вам просто нужно добавить информацию в зависимости к проекту pom.xml. Таким образом, поместье останется неизменным, только cxf-codegen-plugin получит новую зависимость.

В вашем pom.xml

<plugin> 
     <groupId>org.apache.cxf</groupId> 
     <artifactId>cxf-codegen-plugin</artifactId> 
     <version>${cxf-codegen-plugin.version}</version> 
     <executions> 
      <execution> 
       <id>generate-sources</id> 
       <phase>generate-sources</phase> 
       <configuration> 
         <sourceRoot>${project.build.directory}/generated/</sourceRoot> 
         <wsdlOptions> 
          <wsdlOption> 
           <wsdl>${project.basedir}/src/main/resources/wsdl/test.wsdl</wsdl> 
           <wsdlLocation>classpath:wsdl/test.wsdl</wsdlLocation> 
          </wsdlOption> 
          <extraargs> 
           <extraarg>-fe</extraarg> 
           <extraarg>sample</extraarg> 
          </extraargs> 
         </wsdlOptions> 
        </configuration> 
        <goals> 
         <goal>wsdl2java</goal> 
        </goals> 
       </execution> 
      </executions> 
      <dependencies> 
       <dependency> 
       <groupId>org.example.test</groupId>      
       <artifactId>valid-cxf</artifactId> 
       <version>1.0-SNAPSHOT</version> 
      </dependency> 
     </dependencies> 
    </plugin> 

Вот, теперь вы можете полностью управлять тем, что и как генерируется из вашего WSDL.

Полностью рабочий пример можно найти на этом репо https://github.com/babltiga/cxf-valid-sample

+0

Я установил недостающий тег в данном Инструменты- plugin.xml, и я действительно создал и настроил настраиваемый генератор-плагин как зависимость, как вы описали, но я до сих пор не вижу аннотацию @Valid. Как вы думаете, что я могу пропустить? –

+0

Я создам простой проект, чтобы показать, как он работает) и поделиться ссылкой github ... – Babl

+0

В основном, в моем примере просто отсутствовал параметр имени переднего конца, который необходимо передать генератору cxf, добавив ' -fe образец '. Просто просмотрите обновленный файл pom.xml. – Babl

0

Для записи, вот что я думаю, что лучше для реализации CustomSEIGenerator:

package org.example.test; 

import java.util.List; 
import java.util.Map; 

import javax.validation.Valid; 
import javax.xml.namespace.QName; 

import org.apache.cxf.helpers.CastUtils; 
import org.apache.cxf.tools.common.ToolContext; 
import org.apache.cxf.tools.common.ToolException; 
import org.apache.cxf.tools.common.model.JAnnotation; 
import org.apache.cxf.tools.common.model.JavaInterface; 
import org.apache.cxf.tools.common.model.JavaMethod; 
import org.apache.cxf.tools.common.model.JavaModel; 
import org.apache.cxf.tools.common.model.JavaParameter; 
import org.apache.cxf.tools.wsdlto.frontend.jaxws.generators.SEIGenerator; 
import org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.WSDLToJavaProcessor; 

public class CustomSEIGenerator extends SEIGenerator { 

    private static final String VALID_PARAM = "VALID_PARAM"; 

    private static final String VALID_RETURN = "VALID_RETURN"; 

    @Override 
    public void generate(ToolContext penv) throws ToolException { 
    JAnnotation validAnno = new JAnnotation(Valid.class); 
    Map<QName, JavaModel> map = CastUtils.cast((Map<?, ?>) penv.get(WSDLToJavaProcessor.MODEL_MAP)); 
    for (JavaModel javaModel : map.values()) { 
     Map<String, JavaInterface> interfaces = javaModel.getInterfaces(); 

     for (JavaInterface intf : interfaces.values()) { 
     intf.addImport(Valid.class.getCanonicalName()); 
     List<JavaMethod> methods = intf.getMethods(); 

     for (JavaMethod method : methods) { 
      List<JavaParameter> parameters = method.getParameters(); 
      method.addAnnotation(VALID_RETURN, validAnno); 
      for (JavaParameter param : parameters) { 
      param.addAnnotation(VALID_PARAM, validAnno); 
      } 
     } 
     } 
    } 

    super.generate(penv); 
    } 
} 
Смежные вопросы