![](/img/trans.png)
[英]Shoud the Spring request mapping logic map to a handler method based upon the value of servletPath?
[英]Spring mapping Handler doesn't map my curl request to a method
我正在制作我的第一個 RESTful 應用程序,目前遇到一個問題,即 Spring 映射處理程序沒有正確地 map(執行 curl 時,得到 404 Not Found)。 這是我的代碼:
CURL: curl -i -H "接受: application/json" -X GET http://localhost:8080/restaurant-voter/
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"/>
Controller:
@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>
您在@RequestMapping
注釋中缺少restaurant-voter
路徑部分
正確的 URL 應該是
CURL: curl -i -H "Accept: application/json" -X GET http://localhost:8080/rest/restaurants
如果您仍然想使用上下文路徑,請在配置中添加它們:
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/restaurant-voter</url-pattern>
</servlet-mapping>
你能檢查一下 spring-mvc.xml 文件夾下是否存在文件
spring-mvc.xml 在名為 spring 的文件夾名稱下。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.