Question

I am running into a wall on how to configure my application. The goal is to be able to have on the same Tomcat server the following:

  • A full restful service (ie. Hypermedia layer, thus returning application/hal+json format)
  • A rest service service the old fashion way (controller access)
  • A classic set of controller for web pages delivery

Environment is:

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

The repository:

@RepositoryRestResource( path = "u")
public interface IUserRepository extends CrudRepository<Users, Long> {
     Users findByName(@Param("name") String name);
}

The rest controller:

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

The "web" controller:

@Controller
@RequestMapping (value = "/web")
public class HomeController {
@RequestMapping(method = RequestMethod.GET, value = "/home")
public String displayHome(Model model) {
    return "home"
}

The JPA config (to simplify I just put the declaration for the jpa datasource...)

@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 {
...
}

The config for 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;
}
...

}

The config for repository:

@Configuration
@ComponentScan(basePackages = { "com.xxx.controller.rest" })
public class ConfigForRepositoryRestMvc extends RepositoryRestMvcConfiguration {
}

The initializer config:

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[] { "/" };
}
}

Keep in mind the web root context is set to "sr"

When the tomcat server started I can clearly see the mappings happening.

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

The good:

  • when I hit the server on xlocalhostx:8080/sr (sr is the root web context), I do get the list of my restful service in hypermedia fashion like so:

    { "_links" : { "userss" : { "href" : "http://xlocalhostx:8080/sr/u" } } }

  • when I hit the server on xlocalhostx:8080/sr/users I get as expected this:

[{"id":1,"name":"Clark","lastname":"Kent"},{"id":2,"name":"Lois","lastname":"Lane"}]

When I ran the following test, it passes:

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

The bad - when I hit the server on xlocalhostx:8080/sr/web/home I get a 404 because the view resolution process is trying to return a view using a wrong path. ( my home.jsp resides of course under the WEB-INF folders under the views folder. I can clearly see my HomeController is being hit because I have log trace.

What I get back from the server is the following:

a 404 saying: /sr/WEB-INF/viewshome.jsp The requested resource is not available. As you can see the path is not correct at all, I have the root web context ("sr") in the front of it, and missing forward slash before the home.jsp file.

Any ideas are welcome.

Thanks.

Était-ce utile?

La solution

add a slash to the end of the prefix, also have a look at this answer:

private static final String VIEW_RESOLVER_PREFIX = "/WEB-INF/views/";
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top