我在如何配置我的应用程序方面遇到了困难。目标是能够在同一 Tomcat 服务器上具有以下内容:
- 一个完整的restful服务(即超媒体层,从而返回application/hal+json格式)
- 一个休息服务服务的旧方式(控制器访问)
- 一套经典的网页交付控制器
环境是:
<spring-framework.version>4.0.1.RELEASE</spring-framework.version>
<spring-framework.version>4.0.1.RELEASE</spring-framework.version>
<spring-test.version>4.0.1.RELEASE</spring-test.version>
<spring-data-rest-webmvc.version>2.0.0.RC1</spring-data-rest-webmvc.version>
<spring-data-jpa.version>1.4.3.RELEASE</spring-data-jpa.version>
<spring-data-commons.version>1.7.0.RC1</spring-data-commons.version>
存储库:
@RepositoryRestResource( path = "u")
public interface IUserRepository extends CrudRepository<Users, Long> {
Users findByName(@Param("name") String name);
}
其余控制器:
@RestController
@RequestMapping (value = "/users", produces=MediaType.APPLICATION_JSON_VALUE)
public class RestUserController {
@Autowired
private IService service;
@RequestMapping (method = RequestMethod.GET)
public @ResponseBody Iterable<DomainModel.User> findAllUsers() {
return service.findAllUsers();
}
}
“网络”控制器:
@Controller
@RequestMapping (value = "/web")
public class HomeController {
@RequestMapping(method = RequestMethod.GET, value = "/home")
public String displayHome(Model model) {
return "home"
}
JPA 配置(为简化起见,我只是将 jpa 数据源的声明...)
@Configuration
@PropertySource({ "classpath:persistence-mysql.properties" })
@ComponentScan(basePackages = { "com.xxx.controller.rest", com.xxx.services.rest.impl" })
@EnableJpaRepositories(basePackages = "com.xxx.persistence.repository")
@EnableTransactionManagement
public class ConfigForJpa {
...
}
WebMvc 的配置:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.xxx.controller.web" })
public class ConfigForWebMvc extends WebMvcConfigurerAdapter {
private static final String VIEW_RESOLVER_PREFIX = "/WEB-INF/views";
private static final String VIEW_RESOLVER_SUFFIX = ".jsp";
...
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix(VIEW_RESOLVER_PREFIX);
viewResolver.setSuffix(VIEW_RESOLVER_SUFFIX);
return viewResolver;
}
...
}
存储库的配置:
@Configuration
@ComponentScan(basePackages = { "com.xxx.controller.rest" })
public class ConfigForRepositoryRestMvc extends RepositoryRestMvcConfiguration {
}
初始化器配置:
public class WebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { ConfigForJpa.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { ConfigForWebMvc.class,
ConfigForRepositoryRestMvc.class };
}
@Override
protected String getServletName() {
return " ServletName";
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
请记住,Web 根上下文设置为“sr”
当 tomcat 服务器启动时,我可以清楚地看到正在发生的映射。
RequestMappingHandlerMapping - Mapped "{[/web/home],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.xxx.controller.web.HomeController.displayHome
RequestMappingHandlerMapping - Mapped "{[/users/user],methods=[POST],params=[],headers=[],consumes=[],produces=[application/json],custom=[]}" onto public com.xxx.model.DomainModel$User com.xxx.controller.rest.RestUserController
...
SimpleUrlHandlerMapping - Mapped URL path [/resources/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
...
RepositoryRestHandlerMapping - Mapped "{[/{repository}],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.hateoas.Resources
RepositoryRestHandlerMapping - Mapped "{[/],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.data.rest.webmvc.RepositoryLinksResource org.springframework.data.rest.webmvc.RepositoryController.listRepositories()
好的:
当我在 xlocalhostx:8080/sr 上访问服务器时(sr 是根 Web 上下文),我确实以超媒体方式获得了我的 restful 服务列表,如下所示:
{“_links”:{“userss”:{“href”:“
http://xlocalhostx:8080
/sr/u”}}}当我点击服务器时,
xlocalhostx:8080/sr/users
我得到了预期的结果:
[{"id":1,"name":"Clark","lastname":"Kent"},{"id":2,"name":"Lois","lastname":"Lane"}]
当我运行以下测试时,它通过了:
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = { ConfigForWebMvc.class, ConfigForRepositoryRestMvc.class} )
public class HomeControllerTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void getHome() throws Exception {
this.mockMvc.perform(get("/web/home"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(forwardedUrl("/WEB-INF/views/home.jsp"));
}
}
不好的 - 当我在 xlocalhostx:8080/sr/ web/home上访问服务器时,我得到一个 404,因为视图解析过程试图使用错误的路径返回视图。(我的 home.jsp 当然位于 views 文件夹下的 WEB-INF 文件夹下。我可以清楚地看到我的 HomeController 被击中,因为我有日志跟踪。
我从服务器返回的内容如下:
404 说:/sr/WEB-INF/viewshome.jsp 请求的资源不可用。正如您所看到的,路径根本不正确,我在它的前面有根 Web 上下文(“sr”),并且在 home.jsp 文件之前缺少正斜杠。
欢迎任何想法。
谢谢。