reports-service created (prototype xml read with XStream)

This commit is contained in:
akulikov 2022-09-01 18:12:55 +03:00
parent c23e605fa5
commit 38e0bd5790
13 changed files with 490 additions and 0 deletions

View file

@ -0,0 +1,62 @@
<?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">
<modelVersion>4.0.0</modelVersion>
<artifactId>reports-service</artifactId>
<name>reports-service</name>
<description>Service for creating reports</description>
<version>SPCEX-1.0.0.0</version>
<parent>
<artifactId>clearing</artifactId>
<groupId>ru.spcex.clearing</groupId>
<version>SPCEX-1.0.0.0</version>
</parent>
<dependencies>
<!-- Spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.19</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<finalName>${project.artifactId}</finalName>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,21 @@
package ru.spcex.clearing.reports_service;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import ru.spcex.clearing.reports_service.services.ReportsService;
@SpringBootApplication
public class ReportsServiceApplication {
public static void main(String[] args) {
try {
SpringApplicationBuilder builder = new SpringApplicationBuilder(ReportsServiceApplication.class);
builder.run(args);
} catch (Throwable e) {
LoggerFactory.getLogger(ReportsServiceApplication.class).error("DBF-Loader start failed: {} -> {}", e.getClass().getSimpleName(), e.getMessage());
System.exit(-1);
}
ReportsService reportsService = new ReportsService();
reportsService.writeXML(null);
}
}

View file

@ -0,0 +1,12 @@
package ru.spcex.clearing.reports_service.config;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties
@ComponentScan(basePackages = {"ru.spcex.clearing.reports_service"})
public class ReportsServiceConfig {
}

View file

@ -0,0 +1,27 @@
package ru.spcex.clearing.reports_service.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller("/")
public class DefaultController implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
@RequestMapping(method = RequestMethod.GET, path = "/test", produces = MediaType.TEXT_PLAIN_VALUE)
@ResponseBody
public String processGet() {
log.info("Call test method for exporter controller");
return "exporter controller test method";
}
@Override
public void afterPropertiesSet() throws Exception {
log.info("controller started");
}
}

View file

@ -0,0 +1,6 @@
package ru.spcex.clearing.reports_service.exceptions;
public class ConfigException extends RuntimeException {
public ConfigException(String msg) { super(msg); }
public ConfigException(String msg, Throwable cause) { super(msg, cause); }
}

View file

@ -0,0 +1,8 @@
package ru.spcex.clearing.reports_service.properties;
import org.springframework.stereotype.Component;
@Component("reportsServiceProperties")
public class AProperties {
}

View file

@ -0,0 +1,24 @@
package ru.spcex.clearing.reports_service.services;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.AbstractDriver;
import ru.spcex.clearing.reports_service.xml_test.ChildElementForWrite;
import ru.spcex.clearing.reports_service.xml_test.CustomLocalDateConverter;
import ru.spcex.clearing.reports_service.xml_test.RootElementForWrite;
public class ReportsService {
public void writeXML(AbstractDriver driver) {
XStream xStream = driver == null ? new XStream() : new XStream(driver);
// достаточно только для рутового объекта вызвать обработку аннотаций
xStream.processAnnotations(RootElementForWrite.class);
xStream.registerConverter(new CustomLocalDateConverter(), -100);
RootElementForWrite elementForWrite = new RootElementForWrite();
elementForWrite.getTestList().add(new ChildElementForWrite());
elementForWrite.getTestList().add(new ChildElementForWrite());
String dataXml = xStream.toXML(elementForWrite);
System.out.println(dataXml);
}
}

View file

@ -0,0 +1,74 @@
package ru.spcex.clearing.reports_service.xml_test;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
import com.thoughtworks.xstream.converters.basic.BooleanConverter;
// without aliases
public class ChildElementForWrite {
@XStreamAlias("childStr") // alias for field name
private String testChildString = "testChildStr";
@XStreamAsAttribute
private Integer testAttributeInt = Integer.MIN_VALUE;
@XStreamAsAttribute
@XStreamAlias("isBoolean")
@XStreamConverter(value = BooleanConverter.class, booleans = {false}, strings = {"yes", "no"})
private Boolean testYesAttributeBool = Boolean.TRUE;
// @XStreamAlias("booleanField")
// @XStreamConverter(value = BooleanConverter.class, booleans = {true, false}, strings = {"yes", "no"})
// private Boolean testNoFieldBool = Boolean.FALSE;
private Integer testChildInt = Integer.MAX_VALUE;
@XStreamOmitField
private String testIgnoredString = "testIgnore";
public String getTestChildString() {
return testChildString;
}
public void setTestChildString(String testChildString) {
this.testChildString = testChildString;
}
public Integer getTestAttributeInt() {
return testAttributeInt;
}
public void setTestAttributeInt(Integer testAttributeInt) {
this.testAttributeInt = testAttributeInt;
}
public Integer getTestChildInt() {
return testChildInt;
}
public void setTestChildInt(Integer testChildInt) {
this.testChildInt = testChildInt;
}
public String getTestIgnoredString() {
return testIgnoredString;
}
public void setTestIgnoredString(String testIgnoredString) {
this.testIgnoredString = testIgnoredString;
}
public Boolean getTestYesAttributeBool() {
return testYesAttributeBool;
}
public void setTestYesAttributeBool(Boolean testYesAttributeBool) {
this.testYesAttributeBool = testYesAttributeBool;
}
}

View file

@ -0,0 +1,32 @@
package ru.spcex.clearing.reports_service.xml_test;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
// самый большой минус работы с датами: если у какой то даты отличается формат, для нее нужен кастомный конвертер
public class CustomLocalDateConverter implements Converter {
private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
@Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
LocalDate date = (LocalDate) source;
writer.setValue(formatter.format(date));
writer.addAttribute("formatted", "true");
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
// not implemented (not used)
return null;
}
@Override
public boolean canConvert(Class type) {
return LocalDate.class.isAssignableFrom(type);
}
}

View file

@ -0,0 +1,29 @@
package ru.spcex.clearing.reports_service.xml_test;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
@XStreamAlias("withAttrsOnly")
public class ElementWithAttributeOnly {
@XStreamAsAttribute
private String attrStr = "attrStr";
@XStreamAsAttribute
private Long attrLong = Long.MIN_VALUE;
public String getAttrStr() {
return attrStr;
}
public void setAttrStr(String attrStr) {
this.attrStr = attrStr;
}
public Long getAttrLong() {
return attrLong;
}
public void setAttrLong(Long attrLong) {
this.attrLong = attrLong;
}
}

View file

@ -0,0 +1,155 @@
package ru.spcex.clearing.reports_service.xml_test;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@XStreamAlias("root") // alias for classname
public class RootElementForWrite {
@XStreamAlias("string") // alias for field
private String testString = "testString";
private BigDecimal testBigDecimal = new BigDecimal("666.666");
private Double testDouble = Double.MAX_VALUE;
private Long testLong = Long.MIN_VALUE;
private Boolean testBoolean = Boolean.FALSE;
private LocalDate testLocalDateDefault = LocalDate.now();
@XStreamConverter(CustomLocalDateConverter.class)
private LocalDate testLocalDateCustom = LocalDate.now();
private LocalDateTime testLocalDateTime = LocalDateTime.now();
private OffsetDateTime testOffsetDateTime = OffsetDateTime.now();
private Instant testInstant = Instant.now();
@XStreamAlias("namedList")
private List<ChildElementForWrite> testList = new ArrayList<>();
@XStreamImplicit
private List<ChildElementForWrite> testListTwo = Arrays.asList(new ChildElementForWrite(), new ChildElementForWrite());
// can marshal without getter/setter
private ElementWithAttributeOnly elementWithAttributeOnly = new ElementWithAttributeOnly();
public String getTestString() {
return testString;
}
public void setTestString(String testString) {
this.testString = testString;
}
public BigDecimal getTestBigDecimal() {
return testBigDecimal;
}
public void setTestBigDecimal(BigDecimal testBigDecimal) {
this.testBigDecimal = testBigDecimal;
}
public Double getTestDouble() {
return testDouble;
}
public void setTestDouble(Double testDouble) {
this.testDouble = testDouble;
}
public Long getTestLong() {
return testLong;
}
public void setTestLong(Long testLong) {
this.testLong = testLong;
}
public Boolean getTestBoolean() {
return testBoolean;
}
public void setTestBoolean(Boolean testBoolean) {
this.testBoolean = testBoolean;
}
public LocalDate getTestLocalDate() {
return testLocalDateCustom;
}
public void setTestLocalDate(LocalDate testLocalDate) {
this.testLocalDateCustom = testLocalDate;
}
public LocalDateTime getTestLocalDateTime() {
return testLocalDateTime;
}
public void setTestLocalDateTime(LocalDateTime testLocalDateTime) {
this.testLocalDateTime = testLocalDateTime;
}
public OffsetDateTime getTestOffsetDateTime() {
return testOffsetDateTime;
}
public void setTestOffsetDateTime(OffsetDateTime testOffsetDateTime) {
this.testOffsetDateTime = testOffsetDateTime;
}
public Instant getTestInstant() {
return testInstant;
}
public void setTestInstant(Instant testInstant) {
this.testInstant = testInstant;
}
public List<ChildElementForWrite> getTestList() {
return testList;
}
public void setTestList(List<ChildElementForWrite> testList) {
this.testList = testList;
}
public List<ChildElementForWrite> getTestListTwo() {
return testListTwo;
}
public void setTestListTwo(List<ChildElementForWrite> testListTwo) {
this.testListTwo = testListTwo;
}
public LocalDate getTestLocalDateDefault() {
return testLocalDateDefault;
}
public void setTestLocalDateDefault(LocalDate testLocalDateDefault) {
this.testLocalDateDefault = testLocalDateDefault;
}
public LocalDate getTestLocalDateCustom() {
return testLocalDateCustom;
}
public void setTestLocalDateCustom(LocalDate testLocalDateCustom) {
this.testLocalDateCustom = testLocalDateCustom;
}
}

View file

@ -0,0 +1,3 @@
server.port=8080
server.servlet.context-path=/reports_service
spring.main.web-application-type=servlet

View file

@ -0,0 +1,37 @@
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<charset>UTF-8</charset>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>./logs/reports_service.log</file>
<encoder>
<charset>UTF-8</charset>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>
../logs/reports_service.%i.log
</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>10</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>500MB</maxFileSize>
</triggeringPolicy>
</appender>
<root level="warn">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
<logger name="ru.spcex" level="debug" additivity="false">
<appender-ref ref="FILE"/>
<appender-ref ref="CONSOLE"/>
</logger>
</configuration>