3

我在如何配置我的应用程序方面遇到了困难。目标是能够在同一 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 文件之前缺少正斜杠。

欢迎任何想法。

谢谢。

4

1 回答 1

1

在前缀的末尾添加一个斜杠,也看看这个答案

private static final String VIEW_RESOLVER_PREFIX = "/WEB-INF/views/";
于 2014-02-18T22:05:58.027 回答