我正在尝试通过Spring MVC学习Spring hateoas,但无法使其正常工作。我在Google上搜索了很多,但是我在Spring Boot中发现了所有的仇恨 我有一个非常简单的Spring MVC项目。我的pom是
View
要使用hateaos,我要添加其依赖项
<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>com.SpringMvcWeb</groupId>
<artifactId>SpringMvcWebXml</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
但是缺少常见日志记录的给出错误,因此我添加了
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>0.24.0.RELEASE</version>
</dependency>
现在说的是NoSuchMethodError:org.springframework.web.servlet.handler.AbstractHandlerMapping.obtainApplicationContext()
我想念什么? 如果有人可以指导我使用Spring MVC和hateoas代码,那将真的很有帮助。
答案 0 :(得分:0)
我试图重现您的用例。在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>com.SpringMvcWeb</groupId>
<artifactId>SpringMvcWebXml</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<javax-jaxb.version>2.3.0</javax-jaxb.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>0.24.0.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
关键部分是spring-plugin-core和com.fasterxml.jackson.core,我在示例中使用json。我需要spring-plugin-core,因为tomcat错过了这个bean PluginRegistryFactoryBean。
我非常简单的restfull服务如下:
@RestController
public class EndPointSample {
private final MessageLinkFactory messageLinkFactory;
public EndPointSample(MessageLinkFactory messageLinkFactory) {
this.messageLinkFactory = messageLinkFactory;
}
@GetMapping("/test")
public ResponseEntity test(){
return ResponseEntity.ok(messageLinkFactory.getRes(new Message("hello")));
}
}
public class MessageLinkFactory {
public Resource getRes(Message message){
Link link = linkTo(methodOn(EndPointSample.class).test()).withSelfRel();
Resource<Message> hello = new Resource<>(message);
hello.add(link);
return hello;
}
}
public class Message {
private String message;
public Message() { }
public Message(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
结果是一个类似json的
{ message: "hello", _links: {self: { href: "http://localhost:8080/test" } } }
但是,仅当您使用accetp标头application / hal + json发送请求时,此方法才有效。如果您希望它与像spring boot这样的application / json一起使用,则可以为此添加一个消息转换器。我把Spring Boot所采用的代码放进去了。
@Component
class HalMessageConverterSupportedMediaTypesCustomizer
implements BeanFactoryAware {
private volatile BeanFactory beanFactory;
@PostConstruct
public void configureHttpMessageConverters() {
if (this.beanFactory instanceof ListableBeanFactory) {
configureHttpMessageConverters(((ListableBeanFactory) this.beanFactory)
.getBeansOfType(RequestMappingHandlerAdapter.class).values());
}
}
private void configureHttpMessageConverters(
Collection<RequestMappingHandlerAdapter> handlerAdapters) {
for (RequestMappingHandlerAdapter handlerAdapter : handlerAdapters) {
for (HttpMessageConverter<?> messageConverter : handlerAdapter
.getMessageConverters()) {
configureHttpMessageConverter(messageConverter);
}
}
}
private void configureHttpMessageConverter(HttpMessageConverter<?> converter) {
if (converter instanceof TypeConstrainedMappingJackson2HttpMessageConverter) {
List<MediaType> supportedMediaTypes = new ArrayList<>(
converter.getSupportedMediaTypes());
if (!supportedMediaTypes.contains(MediaType.APPLICATION_JSON)) {
supportedMediaTypes.add(MediaType.APPLICATION_JSON);
}
((AbstractHttpMessageConverter<?>) converter)
.setSupportedMediaTypes(supportedMediaTypes);
}
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}
所有这些小步骤应该足以解决我所做的所有问题,并且在我的小型POC中它可以在tomcat 9.0.x上运行。希望对您有帮助