Я написал простой веб-сервис на Java 8 для Eclipse Photon, использующий RestTemplate для публикации (используя postForObject) объекта (называемого патентListWrapper), который упаковывает список объектов (называемый PatentDetails).Я отправляю сообщение из клиента Java (называемого MainWsClient), затем устанавливаю значение вatentDetails на стороне сервера и считываю объектatentListWrapper обратно на клиенте.Это работает нормально, когда на стороне сервера (программа SpringWebServiceHello) использует старую технологию Spring MVC 4 с единственным файлом jar (Spring-web.5.07.RELEASE.jar), следующим за этим - serverSideExample , то есть web.xml и остальные-servlet.xml файлы, контролирующие точку доступа.Затем я написал другую серверную программу (PndGuidRequestWs), используя SpringBoot 2.03 с jar-файлами Spring 5.07 и Maven с идентичным методом @RequestMapping, но без файла web.xml и точки доступа, определенной в файле application.properties:
server.port=8082
server.servlet.path=/
#spring.mvc.servlet.path=/
#server.servlet.contextPath=/
Когда я вызываю эту новую серверную программу с помощью этого клиента - ARC , она также работает нормально, но когда я вызываю ее, используя тот же Java-клиент и точно такой же запрос (очевидно, принимаю для другого URL).Я получаю ошибку 400:
2018-12-18 16:56:53,861 [main] INFO - Running MainWsClient with name = DS fileType = post3
2018-12-18 16:56:54,101 [main] DEBUG - Created POST request for "http://localhost:8082/guidRequest/xmlList"
2018-12-18 16:56:54,145 [main] DEBUG - Setting request Accept header to [application/xml, text/xml, application/json, application/*+xml, application/*+json]
2018-12-18 16:56:54,152 [main] DEBUG - Writing [com.springservice.client.PatentListWrapper@4ba2ca36] using [org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter@3444d69d]
2018-12-18 16:56:54,384 [main] DEBUG - POST request for "http://localhost:8082/guidRequest/xmlList" resulted in 400 (null); invoking error handler
2018-12-18 16:56:54,387 [main] ERROR - DS1B org.springframework.web.client.HttpClientErrorException: 400 null
Не работающая, PndGuidRequestWs, на стороне сервера имеет:
@RestController
public class PndController {
@RequestMapping(value = "/guidRequest/xmlList", method = RequestMethod.POST, produces = { "application/xml" } )
public PatentListWrapper guidSearchList(@RequestBody PatentListWrapper patentListWrapper) {
for (PatentDetails pd : patentListWrapper.getPatentList())
{
pd.setGuid("guidSetOnServer3");
}
return patentListWrapper;
}
}
Рабочая (SpringWebServiceHello) сторона сервера идентична, за исключением:
value = "/service/greeting/xml/post2"
Клиент Java имеет:
public void runCode(String name , String fileType)
{
String url;
if (fileType.equalsIgnoreCase("post2")) {
url = "http://localhost:8080/SpringWebServiceHello/service/greeting/xml/post2";
// This method is identicle to postToPndGuidRequestWs() but this method works fine.
postToSpringWebServiceHello(url);
}else if (fileType.equalsIgnoreCase("post3")) {
url = "http://localhost:8082/guidRequest/xmlList";
// This method gives 404 error
postToPndGuidRequestWs(url);
}
}
private void postToPndGuidRequestWs(String url)
{
PatentListWrapper patentListWrapper = new PatentListWrapper();
PatentDetails pd = new PatentDetails("CN","108552082","A","00000000",12345,"guidIn");
List<PatentDetails> patentList = new ArrayList<PatentDetails>();
patentList.add(pd);
patentListWrapper.setPatentList(patentList);
RestTemplate restTemplate = new RestTemplate();
/* HttpHeaders headers = new HttpHeaders();
headers.add("header_name", "header_value");
headers.setContentType(MediaType.APPLICATION_XML);
HttpEntity<PatentListWrapper> request = new HttpEntity<PatentListWrapper>(patentListWrapper, headers); */
/*List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
Jaxb2RootElementHttpMessageConverter jaxbMessageConverter = new Jaxb2RootElementHttpMessageConverter();
List<MediaType> mediaTypes = new ArrayList<MediaType>();
mediaTypes.add(MediaType.APPLICATION_XML);
jaxbMessageConverter.setSupportedMediaTypes(mediaTypes);
messageConverters.add(jaxbMessageConverter);
restTemplate.setMessageConverters(messageConverters);*/
/* headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_XML));
HttpEntity<String> entity = new HttpEntity<>("parameters", headers);*/
try {
patentListWrapper = restTemplate.postForObject(
url,
patentListWrapper,
PatentListWrapper.class);
logger.debug("DS1A employee obj returned. guid = " + patentListWrapper.getPatentList().get(0).getGuid());
}catch(Exception e) {
logger.error("DS1B " + e);
}
}
}
т.е. fileType = "post2" вызывает SpringWebServiceHello, fileType = "post3" вызывает PndGuidRequestWs.Как видите, я пробовал несколько закомментированных решений, но ничего не работает.Поскольку единственное реальное различие между двумя программами на стороне сервера заключается в том, что ни одна из работающих программ использует загрузку Spring, а рабочая - нет, проблема заключается в настройке SpringBoot, т.е. в структуре каталогов, application.properties или pom.xml.Мой pom.xml содержит:
<?xml version="1.0" encoding="UTF-8"?>
http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0
<groupId>com.clarivate</groupId>
<artifactId>pndguidrequestws</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>pndGuidRequestWs</name>
<description>Guid request webService</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<start-class>com.clarivate.pndguidrequestws.PndGuidRequestWsApplication</start-class>
</properties>
<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>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.1.0</version>
<!-- <scope>provided</scope> --> <!-- DS insert for unix -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Implementing XML Representation for Spring Boot Services -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<!-- httpcomponents jars are Required by PndGuidGenerator -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
</dependencies>
<build>
<finalName>PndGuidRequestWs</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
</project>
Класс PatentListWrapper:
package com.clarivate.pndguidrequestws.model;
import java.util.List;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class PatentListWrapper {
private List<PatentDetails> patentList;
public PatentListWrapper() {}
public List<PatentDetails> getPatentList() {
return patentList;
}
public void setPatentList(List<PatentDetails> patentList) {
this.patentList = patentList;
}
}
Любые предложения приветствуются.
РЕДАКТИРОВАТЬ: Чтобы упростить объект, я создал PatentListWrapper2 только с одним строковым членом:
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class PatentListWrapper2 {
private String name;
public PatentListWrapper2() {}
public PatentListWrapper2(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Я снова могу успешно отправить этот XML с помощью клиента ARC:
<patentListWrapper2>
<name>DSDS</name>
</patentListWrapper2>
с contentType = "application / xml", но когда я пытаюсь отправить патентуListWrapper2 из Java, я получаю непоправимую ошибку:
2018-12-20 09:17:13,931 [main] INFO - Running MainWsClient with name = DS fileType = post4
2018-12-20 09:17:14,166 [main] DEBUG - Created POST request for "http://localhost:8082/guidRequest/xmlList2"
2018-12-20 09:17:14,200 [main] DEBUG - Setting request Accept header to [application/xml, text/xml, application/json, application/*+xml, application/*+json]
2018-12-20 09:17:14,206 [main] DEBUG - Writing [com.springservice.client.PatentListWrapper2@517cd4b] using [org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter@6cc7b4de]
2018-12-20 09:17:14,246 [main] DEBUG - POST request for "http://localhost:8082/guidRequest/xmlList2" resulted in 200 (null)
2018-12-20 09:17:14,248 [main] DEBUG - Reading [com.springservice.client.PatentListWrapper2] as "application/xml;charset=UTF-8" using [org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter@6cc7b4de]
2018-12-20 09:17:14,255 [main] ERROR - DS2B org.springframework.web.client.RestClientException: Error while extracting response for type [class com.springservice.client.PatentListWrapper2] and content type [application/xml;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: Could not unmarshal to [class com.springservice.client.PatentListWrapper2]: unexpected element (uri:"", local:"PatentListWrapper2"). Expected elements are <{}patentListWrapper2>; nested exception is javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"PatentListWrapper2"). Expected elements are <{}patentListWrapper2>
EDIT2 Я запустил pndGuidRequestWs в Eclipse Tomcat вместо - Запускать как -> Spring Boot App,Журнал сервера ниже:
2018-12-20 11:15:45.655 WARN 236 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.clarivate.pndguidrequestws.model.PatentDetails` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('CN'); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.clarivate.pndguidrequestws.model.PatentDetails` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('CN') at [Source: (PushbackInputStream); line: 1, column: 98] (through reference chain: com.clarivate.pndguidrequestws.model.PatentListWrapper["patentList"]->java.util.ArrayList[0])