2012-03-14 16 views
8

Apache Camel için yeni ve alay test ediyorum, işte bu yüzden ...XML eklenmiş ve bazı verileri JPA açıklamalı POJO'ya bağlayan bir Deve yolu nasıl oluşturulur?

Üzerinde etkisi olmayan XSD şeması olan bir XML var. Bu XML'in alt öğeleri, iş pojo'ma bağlamak istediğim verileri tutar. Bu POJO (WeatherCurrent) zaten JPA açıklamalı ve JAXB notu eklemeyi düşünüyordum, böylelikle bölünmüş XML POJO'm ile eşleştirilebilirdi.

Bu XML'in bir kök unsuru olduğundan ve sadece onun childs'ını (metData) istediğim için @XmlRootElement kullanamadığım için POJO'uma nasıl açıklama ekleyeceğim konusunda bir sorunum var.

Bu, kısmi olarak şu bölümde açıklanmıştır: Bölümünü kullanarak Tokenizer dilini kullanarak büyük XML aktarımlarını akış. POJO'm bu örnekte siparişi xml öğesi gibidir. POJO alanlarına eşlemek için metData xml öğesinden yalnızca birkaç öğeye ihtiyacım var.

http://camel.apache.org/jaxb.html de unmarshalling/ayrıca bölüm Kısmi manevra yoktur ama hiçbir JAVA DSL örneği (gerekir), ne de nasıl XML parçaları ile çalışmak pojo açıklama için vardır. Ben kısalık için metdata elemanlarının birçok unsur dışında kalan

<?xml version="1.0" encoding="UTF-8"?> 
<data id="MeteoSI_WebMet_observation_xml"> 
    <language>sl</language> 
    <metData> 
     <domain_altitude>55</domain_altitude> 
     <domain_title>NOVA GORICA</domain_title> 
     <domain_shortTitle>BILJE</domain_shortTitle> 
     <tsValid_issued>09.03.2012 15:00 CET</tsValid_issued> 
     <t_degreesC>15</t_degreesC> 
    </metData> 
    <metData> 
     <domain_meteosiId>KREDA-ICA_</domain_meteosiId> 

: Bu formda

import java.io.File; 

import org.apache.camel.EndpointInject; 
import org.apache.camel.Exchange; 
import org.apache.camel.ProducerTemplate; 
import org.apache.camel.builder.RouteBuilder; 
import org.apache.camel.component.mock.MockEndpoint; 
import org.apache.camel.converter.jaxb.JaxbDataFormat; 
import org.apache.camel.spi.DataFormat; 
import org.apache.camel.test.junit4.CamelTestSupport; 
import org.junit.Test; 

public class WeatherCurrentTest extends CamelTestSupport { 

    @EndpointInject(uri = "file:src/test/resources") 
    private ProducerTemplate inbox; 

    @Override 
    protected RouteBuilder createRouteBuilder() throws Exception { 
     return new RouteBuilder() { 
      @Override 
      public void configure() throws Exception { 
       DataFormat jaxbDataFormat = new JaxbDataFormat("com.mycompany.model.entities.weather");// WARNING two packages for JaxbDataFormat 

       from("file:src/test/resources/?fileName=observation_si_latest.xml&noop=true&idempotent=false") 
       .split() 
       .tokenizeXML("metData") 
       .unmarshal(jaxbDataFormat) 
       .to("mock:meteo");   
      } 
     }; 
    } 

    @Test 
    public void testMetData() throws Exception { 
     MockEndpoint mock = getMockEndpoint("mock:meteo"); 
     mock.expectedMessageCount(9); 

     File meteo = new File("src/test/resources/observation_si_latest.xml"); 
     String content = context.getTypeConverter().convertTo(String.class, meteo); 
     inbox.sendBodyAndHeader(content, Exchange.FILE_NAME, "src/test/resources/observation_si_latest.xml"); 

     mock.assertIsSatisfied(); 
    } 

} 

XML (observation_si_latest.xml) gelir:

Şimdiye kadar bu test kodu var . Ben JPA açıklamalı POJO'nun istasyon alanına (diğerlerinin yanı sıra) domain_title eşlemek ve daha sonra bir akıllı ve kısa Camel rotasında tüm umarım veritabanını kaydetmek istiyorum.

POJO (hayır JAXB henüz ek notların): Ben de alanları ve yöntemlerinin çok dışında kalan

@Entity 
@Table(name="weather_current") 
public class WeatherCurrent implements Serializable { 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int id; 

    private String station; 

    @Temporal(TemporalType.TIMESTAMP) 
    @Column(name="successfully_updated") 
    private Date successfullyUpdated; 

    private short temperature; 

    @Column(name="wind_direction") 
    private String windDirection; 

} 

.

Böylece fikir WeatherCurrent Pojo en istasyon alanına * DOMAIN_TITLE * değerini haritaya ve her metdata elemanı için bunu ve WeatherCurrent veritabanına nesneleri listesini kaydetmek olduğunu.

Bunu nasıl uygulayacağınız konusunda en iyi tavsiyemiz memnuniyetle karşılanır.

+0

Öncelikle bölünmüş bir parametre alır. İkincisi xpath veya xlst XML'den veri kaldırmak nasıl? XML'yi Marshal yapabilir veya xpath veya xlst ile verilere erişebilirsiniz. En iyi ne işe yarıyor? – chrislovecnm

cevap

2

Bu, @XmlRootElement öğesini kullanamadığına dair yanlış bir varsayımda bulundum. POJO'ya not ekledikten ve jaxb.index dosyasını ekledikten sonra rota ve test başarı ile geçiyor. Şimdi bir trende olduğum için çözümü daha sonra veya yarın postalayacağım.

Saatler sonra ... (JPA olanlar üzerine) POJO üzerinde

JAXB ek açıklamaları:

@Entity 
@Table(name="weather_current") 
@XmlRootElement(name = "metData") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class WeatherCurrent implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int id; 

    @XmlElement(name = "nn_shortText") 
    private String conditions; 

    @XmlElement(name = "rh") 
    private short humidity; 

    @XmlElement(name = "msl") 
    private short pressure; 

    @Column(name="pressure_tendency") 
    @XmlElement(name = "pa_shortText") 
    private String pressureTendency; 

    @Temporal(TemporalType.TIMESTAMP) 
    @XmlElement(name = "tsValid_issued") 
    private Date published; 

    @XmlElement(name = "domain_longTitle") 
    private String station; 

WeatherCurrent Exchage nesnelerin listesini almak için etkin.

.unmarshal(jaxbDataFormat).bean(EchoBean.class, "printWeatherStation") 

ve EchoBean:

public class EchoBean { 

    public String printWeatherStation(WeatherCurrent weatherCurrent) { 
     return weatherCurrent.getStation(); 
    } 
} 

güzel log Deve bileşeni ile hava istasyonlarının isimlerini yazdıran Sadece test için ben bir özelliği yazdırmak için benim EchoBean her biri yönlendirilir.

bana http://camel.apache.org/jaxb.html de açıkça JAXB bağlam pom.xml olarak

DataFormat jaxb = new JaxbDataFormat("com.acme.model"); 
+1

Bir JAXB gereksinimi, bir jaxb.index dosyanız var veya özel bir ObjectFactory sağlıyorsunuz. NewInstance yöntemi için javadoc'a bakın: http://docs.oracle.com/javase/6/docs/api/javax/xml/bind/JAXBContext.html –

2

başlatılır söylüyor rağmen WeatherCurrent java kaynağı yanındaki bu jaxb.index dosyasını koymak zorunda olmasıydı rahatsız bir belgesiz şey

<dependency> 
     <groupId>org.apache.camel</groupId> 
     <artifactId>camel-jaxb</artifactId> 
     <version>2.13.0</version> 
    </dependency> 

Sonraki (name = "çalışan") @XmlRootElement ile pojo sınıfını açıklama

- aşağıdaki bağımlılık içerir
package com.javainuse.model; 

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement(name = "employee") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Employee { 

    private String empName; 
    private int empId; 

    public String getEmpName() { 
     return empName; 
    } 

    public void setEmpName(String empName) { 
     this.empName = empName; 
    } 

    public int getEmpId() { 
     return empId; 
    } 

    public void setEmpId(int empId) { 
     this.empId = empId; 
    } 
} 

Son olarak, RouteBuilder sınıfında jaxb veri formunu tanımlayın ve rotada kullanın.

// XML Data Format 
     JaxbDataFormat xmlDataFormat = new JaxbDataFormat(); 
     JAXBContext con = JAXBContext.newInstance(Employee.class); 
     xmlDataFormat.setContext(con); 

from("file:C:/inputFolder").doTry().unmarshal(xmlDataFormat). 
     process(new MyProcessor()).marshal(jsonDataFormat). 
     to("jms:queue:javainuse") 

Kaynak Kodu ve daha fazla ayrıntı - Apache Camel - Marshalling/Unmarshalling XML/JSON Data

İlgili konular