I am working on setting up swagger2 documentation for my Spring REST Project. But when I try to execute http://localhost:8085/swagger-ui.html returns empty page.The problem is my bean class is not loaded by my spring MVC application and it is NOT a spring boot application.
The below is my swagger2 config class
#Configuration
#EnableSwagger2
#EnableWebMvc
public class SwaggerConfig extends WebMvcConfigurerAdapter{
#Bean
public Docket newsApi() {
System.out.println("!#################################################22");
return new Docket(DocumentationType.SWAGGER_2)
.groupName("Dialr")
.apiInfo(apiInfo())
.select()
.paths(regex("/*.*"))
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Spring REST Sample with Swagger")
.description("Spring REST Sample with Swagger")
.termsOfServiceUrl("http://www-03.ibm.com/software/sla/sladb.nsf/sla/bm?Open")
.contact("Niklas Heidloff")
.license("Apache License Version 2.0")
.licenseUrl("https://github.com/IBM-Bluemix/news-aggregator/blob/master/LICENSE")
.version("2.0")
.build();
}
}
The below is my rest-servlet.xml under WEB-INF
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:component-scan base-package="com.xx.yy.zz" />
<mvc:annotation-driven />
<mvc:resources mapping="swagger-ui.html" location="classpath:/META-INF/resources/"/>
<mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/"/>
<context:annotation-config/>
<bean name="swaggerConfig" class="com.xx.yy.SwaggerConfig"/>
</beans>
Please find the web.xml entry as well
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Retail_SVC</display-name>
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/rest-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Please let me know if anything is missing ? Any help is highly appreciated.
Since the base url mapping in your servlet mapping is /rest/* the swagger-ui.html will not load to http://localhost:8085/swagger-ui.html so
try with http://localhost:8085/rest/swagger-ui.html it may work
I used the WebMvcConfigurer instead of the WebMvcConfigurerAdapter because that class is already deprecated.
#Configuration
#EnableSwagger2
public class SwaggerConfig implements WebMvcConfigurer {
#Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.illary.controller"))
.paths(PathSelectors.any())
.build()
.apiInfo(metaData());
}
private ApiInfo metaData() {
return new ApiInfoBuilder()
.title("Spring Boot Swagger App")
.description("\"Spring Boot Swagger Server App\"")
.version("1.0.0")
.license("Apache License Version 2.0")
.licenseUrl("https://www.apache.org/licenses/LICENSE-2.0\"")
.build();
}
public ApiInfo apiInfo() {
final ApiInfoBuilder builder = new ApiInfoBuilder();
builder.title("Swagger Test App").version("1.0").license("(C) Copyright Test")
.description("The API provides a platform to query build test swagger api");
return builder.build();
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
Related
Trying to apply MVC Spring Validation to my web project. I think I have everything configured properly, but my form is not being validated.
I am not using Maven or Gradle. Rather, I am including the jar files I was told I needed by my tutorial in my build path.
The jar files are:
validation-api-1.1.0.Final.jar
hibernate-validator-5.0.1.Final.jar
I am following this tutorial: https://www.codejava.net/frameworks/spring/spring-mvc-form-validation-example-with-bean-validation-api
My config.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<mvc:annotation-driven />
</beans>
My Model:
package bl;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotEmpty;
public class VendorValidation {
#NotEmpty
#Size(min = 1, message = "Field requires an entry")
private String vname;
#NotEmpty
private String vphone;
#NotEmpty
private String vemail;
#NotEmpty
private String vcity;
#NotEmpty
private String vstate;
#NotEmpty
private String vcountry;
#NotEmpty
private String vzipcode;
#NotEmpty
private String vtimezone;
public String getVname() {
return vname;
}
public void setVname(String vname) {
this.vname = vname;
}
public String getVphone() {
return vphone;
}
public void setVphone(String vphone) {
this.vphone = vphone;
}
public String getVemail() {
return vemail;
}
public void setVemail(String vemail) {
this.vemail = vemail;
}
public String getVcity() {
return vcity;
}
public void setVcity(String vcity) {
this.vcity = vcity;
}
public String getVstate() {
return vstate;
}
public void setVstate(String vstate) {
this.vstate = vstate;
}
public String getVcountry() {
return vcountry;
}
public void setVcountry(String vcountry) {
this.vcountry = vcountry;
}
public String getVzipcode() {
return vzipcode;
}
public void setVzipcode(String vzipcode) {
this.vzipcode = vzipcode;
}
public String getVtimezone() {
return vtimezone;
}
public void setVtimezone(String vtimezone) {
this.vtimezone = vtimezone;
}
}
My View:
<form:form method="post" id="va-form" action="insertVendor" modelAttribute="vendorValidation">
<div class="form-group">
<label>Vendor Name</label> <form:input type="text" path="vname" class="form-control"
id="nameForm" />
</div>
...
</form:form>
My Controller:
#RequestMapping(value = "vendorForm", method = RequestMethod.GET)
public String formView(ModelMap map, HttpServletRequest request) {
VendorValidation vendorValidation = new VendorValidation();
map.put("vendorValidation", vendorValidation);
return "vendorForm";
}
RequestMapping(value = "/insertVendor", method = RequestMethod.POST)
public String insertVendor(#Valid #ModelAttribute("vendorValidation") VendorValidation vendorValidation, BindingResult result,
HttpServletRequest request, ModelMap model) {
System.out.println("Found form errors: " + result.hasErrors());
if (result.hasErrors())
{
return "vendorForm";
}
else
{
// database logic
return "vendormanagement";
}
}
The BindingResult object does not contain any errors when attempting to submit the form and it should when I leave my fields empty. So the if (result.hasErrors()) does not fire and I get a database exception for trying to insert null values.
Download the Spring framework "-dist.zip" from here - https://repo.spring.io/release/org/springframework/spring/
Download hibernate ORM zip - https://sourceforge.net/projects/hibernate/files/hibernate-orm/5.4.2.Final/hibernate-release-5.4.2.Final.zip/download
Add jar from directory - hibernate-release-5.4.2.Final\lib\required
Download hibernate validator - https://sourceforge.net/projects/hibernate/files/hibernate-validator/6.0.16.Final/hibernate-validator-6.0.16.Final-dist.zip/download
Add jars present outside : hibernate-validator-6.0.16.Final\dist
Remember : Add all the jars to the classpath.
Now, I'm providing a sample code to demonstrate :
spring.xml or application-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan
base-package="com.demo" />
<mvc:annotation-driven />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- Add custom message resources -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="resources/message"></property>
</bean>
</beans>
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>project</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
I think that this will solve your problem.
I am trying to convert my servlet-context.xml file to Servlet Config.java and there is no compile time error. But at run time, my server shows that no request mapping for /product/.
My web.xml is
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocatation</param-name>
<param-value>com.mds.test.ServetConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
and my ServletConfig is:
package com.mds.test;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#ComponentScan(basePackages={"com.mds.test"})
#EnableWebMvc
public class ServletConfig extends WebMvcConfigurerAdapter{
#Bean
public ViewResolver internalResourceViewer(){
InternalResourceViewResolver irvr= new InternalResourceViewResolver();
irvr.setPrefix("/WEB-INF/views/");
irvr.setSuffix(".jsp");
return irvr;
}
#Bean(name="multipartResolver")
public ExtendedMultipartResolver resolver(){
return new ExtendedMultipartResolver();
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// TODO Auto-generated method stub
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
Can you tell what I am missing. Thanks in advance
Sorry guys, I was doing a very little but confusing mistake. I was writing wrong class name. Class name should be com.mds.test.ServletConfig not the com.mds.test.ServetConfig in web.xml
So guys you can take it as a simple converter from xml to java file.
I am facing issues with #PreAuthorize annotation. There are two things to be done.
Retrieving all employees should be done by one who has the authority USER or ADMIN.
Deleting employee should be done by one with authority only ADMIN.
I need to use method level authorization with spring-security-4.
User.java
package com.nikunj.SpringMethodLevelAuthorization;
public class user {
int id;
String firstName;
String type;
public user(int id, String firstName, String type){
this.id = id;
this.firstName = firstName;
this.type = type;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
userService.java
package com.nikunj.SpringMethodLevelAuthorization;
import java.util.Vector;
import org.springframework.security.access.prepost.PreAuthorize;
public interface userService {
#PreAuthorize("hasRole('ADMIN')")
public void deleteUser(int id);
#PreAuthorize("hasRole('ADMIN') or hasRole('USER')")
public Vector<user> getAllUsers();
}
userImplementation.java
package com.nikunj.SpringMethodLevelAuthorization;
import java.util.Vector;
public class userImplementation implements userService {
Vector<user> users;
public userImplementation(){
users = new Vector<user>();
users.add(new user(1,"Nikunj","SE"));
users.add(new user(2,"Abdul","SSE"));
users.add(new user(3,"Mrinal","LSE"));
users.add(new user(4,"Anurag","SE"));
users.add(new user(5,"Naresh","LSE"));
users.add(new user(6,"Mahesh","SE"));
}
public user findById(int id){
for(user u : users){
if(u.getId()==id){
return u;
}
}
return null;
}
public Vector<user> getAllUsers(){
return users;
}
public void deleteUser(int id){
user u = findById(id);
users.remove(u);
}
}
homeController.java
package com.nikunj.SpringMethodLevelAuthorization;
import java.util.Vector;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class HomeController {
userImplementation ui=new userImplementation();
Vector<user> users;
#RequestMapping(value = { "/users" },method = RequestMethod.GET)
public String getAllUsers(Model model) {
System.out.println("in getAll()");
users=ui.getAllUsers();
model.addAttribute("users", users);
return "allUsers";
}
#RequestMapping(value = { "/delete/{id}" }, method = RequestMethod.GET)
public String deleteUser(#PathVariable int id,Model model){
System.out.println("in delete()");
ui.deleteUser(id);
users=ui.getAllUsers();
model.addAttribute("users", users);
return "allUsers";
}
}
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="com.nikunj.SpringMethodLevelAuthorization" />
</beans:beans>
spring-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd">
<http auto-config="true">
<intercept-url pattern="/" access="hasRole('USER') or hasRole('ADMIN')" />
</http>
<!-- Eable method level security -->
<global-method-security pre-post-annotations="enabled"/>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="abdul" password="root123" authorities="ROLE_ADMIN"/>
<user name="nikunj" password="secret" authorities="ROLE_USER"/>
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- Processes application requests -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/dispatcher-servlet.xml
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring Security Configuration -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Make userImplementation as a Spring bean and inject it into the HomeController either by annotation or by define it in xml.
<beans:bean name="userService" class="com.nikunj.SpringMethodLevelAuthorization.userImplementation" />
OR
#Service
public class userImplementation implements userService {
....
....
}
Then autowire it in HomeController.
#Controller
public class HomeController {
//userImplementation ui=new userImplementation();
#Autowired
UserService ui;
......
......
}
I am trying to implement an embedded jetty server using spring mvc for dispatching. I tried several tutorials but monstyl they are out of date or don't use embedded jetty.
So far I created a new spring mvc project from scratch in intellij idea.
src/
main/
java/
com.springapp.mvc/
HelloController.java
Launcher.java
webapp/
WEB-INF/
mvc-dispatcher-servlet.xml
web.xml
pom.xml
HelloController.java
#Controller
#RequestMapping("/")
public class HelloController {
#RequestMapping(method = RequestMethod.GET)
public String printWelcome(ModelMap model) {
model.addAttribute("message", "Hello world!");
return "hello";
}
}
Launcher.java
public class Launcher {
public static void main(String[] args) throws Exception {
Server server = new Server(8080);
//todo: implementation to use dispatcher-servlet...
server.start();
server.join();
}
}
mvc-dispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.springapp.mvc"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
web.xml
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring MVC Application</display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
How do I tell the server correctly to use the dispatcher servlet?
I tried a few things out but nothing really worked yet.
The solution for everyone who is also interested... (in scala not in java)
val server: Server = new Server(8080)
private val root: WebAppContext = new WebAppContext
root.setContextPath("/")
root.setDescriptor("src/main/webapp/web.xml")
root.setResourceBase("src/main/webapp/"))
root.setParentLoaderPriority(true)
server.setHandler(root)
server.start()
server.join()
When i create MockMvc for restful-webservice testing with spring MVC 3.2.3 using WebApplicationContext like this:
#Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
#Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
// ...
}
Then when i run my test, it will fail with return code 404 and my log says that
Did not find handler method for [my/path]
But if i change to this way
public class MyWebTests {
private MockMvc mockMvc;
#Before
public void setup() {
this.mockMvc = MockMvcBuilders.standaloneSetup(new AccountController()).build();
}
// ...
}
Then my test will run well without any error.
The only difference i know is that if i use WebApplicationContext to create MockMvc then it will load my Spring Confuguration, while if i use Controller then it will not.
What can possibly cause that error (did not find handler method ...) in my case?
EDIT
My test class
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("classpath:restful-test-context.xml")
#WebAppConfiguration
public class TestSourceController {
#Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
private ObjectMapper mapper;
#Autowired
DeviceDAO deviceDAO;
#AfterClass
public static void tearDownAfterClass() throws Exception {
}
#Before
public void setUp() throws Exception {
Mockito.reset(deviceDAO);
mockMvc = MockMvcBuilders.standaloneSetup(new SourceController()).build();
mapper = new ObjectMapper();
}
#After
public void tearDown() throws Exception {
}
#Test
public void testGetAllDevice() throws UnsupportedEncodingException,
Exception {
Device device1 = new Device();
device1.setId("switch1");
device1.setIsRoot(true);
device1.setName("switch1");
device1.setStatus("ONLINE");
device1.setType("SWITCH");
Device device2 = new Device();
device2.setId("switch2");
device2.setIsRoot(true);
device2.setName("switch2");
device2.setStatus("OFFLINE");
device2.setType("SWITCH");
List<Device> devices = Arrays.asList(device1, device2);
when(deviceDAO.getAllDevices()).thenReturn(devices);
String expected = mapper.writeValueAsString(devices);
String result = mockMvc
.perform(get("/api/devices").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk()).andReturn().getResponse()
.getContentAsString();
verify(deviceDAO).getAllDevices();
assertEquals(expected, result);
}
}
My Controller
#Controller
public class SourceController {
private static final Logger logger = LoggerFactory.getLogger("SourceController");
#RequestMapping(value = "/api/devices", method = RequestMethod.GET)
#ResponseBody
public List<Device> getAllDevice() {
DeviceDAO deviceDAO = AppContext.getService(DeviceDAO.class,
"deviceDAO");
logger.info("The deviceDAO is" + deviceDAO.toString() + "!");
return deviceDAO.getAllDevices();
}
}
My web.xml
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>Spring Web MVC Application</display-name>
<servlet>
<servlet-name>nhduc-training-app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>nhduc-training-app</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/nhduc-training-app-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
My restful-test-context.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-1.5.xsd">
<context:annotation-config />
<mvc:annotation-driven />
<context:component-scan base-package="com.tma.nhduc.controller" />
<bean id="daoUtils" class="com.tma.nhduc.dao.DAOUtils" />
<bean id="counterService" class="com.tma.nhduc.dao.SequenceService" />
<bean id="portDAO" class="com.tma.nhduc.dao.PortDAO" />
<bean id="alarmDAO" class="com.tma.nhduc.dao.AlarmDAO" />
<bean id="deviceDAO" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="com.tma.nhduc.dao.DeviceDAO"></constructor-arg>
</bean>
<bean id="appContext" class="com.tma.nhduc.ctx.AppContext" />
<mongo:mongo host="localhost" port="27017" />
<mongo:db-factory dbname="nms" mongo-ref="mongo" />
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>
MockMvc expect Controller class initialization.See how i have done this.
#InjectMocks
private SampleController controller = new SampleController();
#Before
public void before() {
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
.dispatchOptions(true).build();
}