Я делаю свое первое приложение RESTful и в настоящее время у меня проблема с тем, что обработчик сопоставления Spring не отображается должным образом (при выполнении curl, получить 404 Not Found). Вот мой код:
CURL: curl -i -H "Принять: application / json" -X GET http://localhost:8080/restaurant-voter/rest/restaurants
web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<display-name>Topjava</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring/spring-app.xml
classpath:spring/spring-db.xml
</param-value>
</context-param>
<!-- Spring MVC -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-mvc.xml</param-value>
</init-param>
<init-param>
<param-name>throwExceptionIfNoHandlerFound</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Spring-mvc.xml
<context:component-scan base-package="ru.vadimmazitov.**.web"/>
<!-- all resources inside folder src/main/webapp/resources are mapped so they can be referred to inside JSP files -->
<mvc:resources mapping="/resources/**" location="/resources/"/>
<bean class="ru.vadimmazitov.voter.web.json.JacksonObjectMapper" id="objectMapper" factory-method="getMapper"/>
<mvc:annotation-driven conversion-service="conversionService">
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="objectMapper"/>
</bean>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<!-- <property name="supportedMediaTypes">-->
<!-- <list>-->
<!-- <value>text/plain;charset=UTF-8</value>-->
<!-- <value>text/html;charset=UTF-8</value>-->
<!-- </list>-->
<!-- </property>-->
</bean>
</mvc:message-converters>
<mvc:argument-resolvers>
<bean class="org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver "/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
<bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean" id="conversionService">
<property name="formatters">
<set>
<bean class="ru.vadimmazitov.voter.web.converter.DateTimeFormatters.LocalTimeFormatter"/>
<bean class="ru.vadimmazitov.voter.web.converter.DateTimeFormatters.LocalDateFormatter"/>
</set>
</property>
</bean>
<security:global-method-security secured-annotations="enabled" pre-post-annotations="enabled"/>
Контроллер:
@RestController
@RequestMapping(value = "/rest/restaurants", produces = MediaType.APPLICATION_JSON_VALUE)
public class RestaurantRestController {
private final Logger log = getLogger(getClass());
private RestaurantService service;
@Autowired
public void setService(RestaurantService service) {
this.service = service;
}
@GetMapping
public List < Restaurant > getAll() {
log.info("get all restaurants");
return service.getAll();
}
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.CREATED)
public ResponseEntity < Restaurant > create(@Validated(View.Web.class) @RequestBody Restaurant restaurant) {
log.info("create {}", restaurant);
checkNew(restaurant);
int userId = SecurityUtil.authUserId();
Restaurant created = service.create(userId, restaurant);
URI uriOfNewResource = ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/rest/restaurants/{id}")
.buildAndExpand(created.getId()).toUri();
return ResponseEntity.created(uriOfNewResource).body(created);
}
@PutMapping(value = "/{id}", consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.NO_CONTENT)
public void update(@Validated(View.Web.class) @RequestBody Restaurant restaurant, @PathVariable("id") int id) {
log.info("update {} with id {}", restaurant, id);
assureIdConsistent(restaurant, id);
int userId = SecurityUtil.authUserId();
service.update(userId, restaurant);
}
@GetMapping(value = "/{id}")
public Restaurant get(@PathVariable("id") int id) {
log.info("get restaurant with id={}", id);
return service.get(id);
}
}
Pom.xml
<?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>
<groupId>
vasyapupkin
</groupId>
<artifactId>
graduation
</artifactId>
<version>
1.0-SNAPSHOT
</version>
<packaging>
war
</packaging>
<name>
Voter
</name>
<url>
http://voter.herokuapp.com/
</url>
<properties>
<java.version>
11
</java.version>
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
<project.reporting.outputEncoding>
UTF-8
</project.reporting.outputEncoding>
<spring.version>
5.1.7.RELEASE
</spring.version>
<spring.security.version>
5.1.5.RELEASE
</spring.security.version>
<spring-data-jpa.version>
2.1.9.RELEASE
</spring-data-jpa.version>
<spring-context.version>
5.2.0.RELEASE
</spring-context.version>
<tomcat.version>
9.0.22
</tomcat.version>
<jackson-json.version>
2.9.10
</jackson-json.version>
<!-- Hibernate -->
<hibernate.version>
5.4.3.Final
</hibernate.version>
<hibernate-validator.version>
6.0.17.Final
</hibernate-validator.version>
<javax-el.version>
3.0.1-b11
</javax-el.version>
<!-- Tools -->
<ehcache.version>
3.7.1
</ehcache.version>
<!-- Logging -->
<logback.version>
1.2.3
</logback.version>
<slf4j.version>
1.7.25
</slf4j.version>
<!-- Testing -->
<junit.jupiter.version>
5.5.1
</junit.jupiter.version>
</properties>
<build>
<finalName>
topjava
</finalName>
<defaultGoal>
package
</defaultGoal>
<plugins>
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-compiler-plugin
</artifactId>
<version>
3.7.0
</version>
<configuration>
<source>
${java.version}
</source>
<target>
${java.version}
</target>
</configuration>
</plugin>
<plugin>
<!-- https://junit.org/junit5/docs/current/user-guide/#running-tests-build-maven -->
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-surefire-plugin
</artifactId>
<version>
2.22.1
</version>
<configuration>
<argLine>
-Dfile.encoding=UTF-8
</argLine>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Logging with SLF4J & LogBack -->
<dependency>
<groupId>
org.slf4j
</groupId>
<artifactId>
slf4j-api
</artifactId>
<version>
${slf4j.version}
</version>
<scope>
compile
</scope>
</dependency>
<dependency>
<groupId>
ch.qos.logback
</groupId>
<artifactId>
logback-classic
</artifactId>
<version>
${logback.version}
</version>
<scope>
runtime
</scope>
</dependency>
<!-- DB -->
<dependency>
<groupId>
org.hsqldb
</groupId>
<artifactId>
hsqldb
</artifactId>
<version>
2.4.0
</version>
</dependency>
<!-- JSON -->
<dependency>
<groupId>
com.fasterxml.jackson.core
</groupId>
<artifactId>
jackson-databind
</artifactId>
<version>
${jackson-json.version}
</version>
</dependency>
<dependency>
<groupId>
com.fasterxml.jackson.datatype
</groupId>
<artifactId>
jackson-datatype-hibernate5
</artifactId>
<version>
${jackson-json.version}
</version>
</dependency>
<dependency>
<groupId>
com.fasterxml.jackson.datatype
</groupId>
<artifactId>
jackson-datatype-jsr310
</artifactId>
<version>
${jackson-json.version}
</version>
</dependency>
<!-- - ORM -->
<dependency>
<groupId>
org.hibernate
</groupId>
<artifactId>
hibernate-core
</artifactId>
<version>
${hibernate.version}
</version>
</dependency>
<dependency>
<groupId>
org.hibernate.validator
</groupId>
<artifactId>
hibernate-validator
</artifactId>
<version>
${hibernate-validator.version}
</version>
</dependency>
<dependency>
<groupId>
org.hibernate
</groupId>
<artifactId>
hibernate-jcache
</artifactId>
<version>
${hibernate.version}
</version>
</dependency>
<dependency>
<groupId>
org.glassfish
</groupId>
<artifactId>
javax.el
</artifactId>
<version>
${javax-el.version}
</version>
<scope>
provided
</scope>
</dependency>
<!-- Cache -->
<dependency>
<groupId>
javax.cache
</groupId>
<artifactId>
cache-api
</artifactId>
<version>
1.1.0
</version>
</dependency>
<dependency>
<groupId>
org.ehcache
</groupId>
<artifactId>
ehcache
</artifactId>
<!-- <scope>runtime</scope> -->
<version>
${ehcache.version}
</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-context-support
</artifactId>
<!-- <version>${spring-context.version}</version> -->
</dependency>
<dependency>
<groupId>
org.springframework.data
</groupId>
<artifactId>
spring-data-jpa
</artifactId>
<version>
${spring-data-jpa.version}
</version>
</dependency>
<!-- Web -->
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-webmvc
</artifactId>
<version>
5.1.5.RELEASE
</version>
</dependency>
<dependency>
<groupId>
org.apache.tomcat
</groupId>
<artifactId>
tomcat-servlet-api
</artifactId>
<version>
${tomcat.version}
</version>
<scope>
provided
</scope>
</dependency>
<!-- security -->
<dependency>
<groupId>
org.springframework.security
</groupId>
<artifactId>
spring-security-web
</artifactId>
<version>
${spring.security.version}
</version>
</dependency>
<dependency>
<groupId>
org.springframework.security
</groupId>
<artifactId>
spring-security-config
</artifactId>
<version>
${spring.security.version}
</version>
</dependency>
<dependency>
<groupId>
org.springframework.security
</groupId>
<artifactId>
spring-security-taglibs
</artifactId>
<version>
${spring.security.version}
</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>
org.junit.jupiter
</groupId>
<artifactId>
junit-jupiter-engine
</artifactId>
<version>
${junit.jupiter.version}
</version>
<scope>
test
</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-framework-bom
</artifactId>
<version>
${spring.version}
</version>
<type>
pom
</type>
<scope>
import
</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>