Spring hateoas with Spring Mvc

Multi tool use
Multi tool use


Spring hateoas with Spring Mvc



I am trying to learn Spring hateoas with spring MVC but not able to make it work. I googled a lot but all I found hateoas with Spring Boot
I have very simple working Spring MVC project. My pom is


<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>





to use hateaos I add its dependency


<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>0.24.0.RELEASE</version>
</dependency>



but its giving error common logging is missing, so I add


<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>



now its saying NoSuchMethodError: org.springframework.web.servlet.handler.AbstractHandlerMapping.obtainApplicationContext()



what am I missing?
if someone could direct me to working Spring MVC and hateoas code it would be really helpful.




1 Answer
1



I tried to reproduce your use case. on pom.xml should be like below:


<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>



The critical part hear is spring-plugin-core and com.fasterxml.jackson.core, I use json in my sample. I needed of spring-plugin-core because tomcat miss this bean PluginRegistryFactoryBean.



the my very simple restfull servie is like below:


@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;
}
}



the result is a json like:


{ message: "hello", _links: {self: { href: "http://localhost:8080/test" } } }



however it works only if you send a request with accetp header application/hal+json. if you want that it works even with application/json like in spring boot you can add a message converter for this. I put the code taken by spring boot that do it .


@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;
}

}



all this small steps should be enough for fix all your problem I do it and in my small POC it works on tomcat 9.0.x. I hope that this can help you






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

by9aUn,KFZIJKlj,XcpupgKrHsXikVwm Vgvg,TfHIPN1
ZVca9U4GWX1Ruh1oZqPAsmyGBdW,H Bdm,SCPsDMJMO 0G su3h4R,TvNzg53hl

Popular posts from this blog

PHP contact form sending but not receiving emails

Do graphics cards have individual ID by which single devices can be distinguished?

Create weekly swift ios local notifications