Spring MVC Junit testing MultipartFile always empty - java

I'm using spring-mvc version 4.1.6-RELEASE with Junit 4.12 and java 1.7, I have a controller for file uploading who works when I've tested it on server with Browser. But when I try to test it with junit the mockfilemultipart is always empty and I'm sure isn't so in the test class.
This is my servlet-context.xml
<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">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- beans:import resource="../controller-context.xml"/-->
<!-- 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>
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
<context:component-scan base-package="it.isfol.iweb" />
This is the controller
package it.isfol.iweb.controller.pianoattivita;
import it.isfol.iweb.bean.wrappers.PianoAttivitaWrapper;
import it.isfol.iweb.controller.common.IsfolController;
import it.isfol.iweb.exceptions.IWebFatalException;
import it.isfol.iweb.service.pianoattivita.FilePianoAttivitaService;
import it.isfol.iweb.util.SessionConstant;
import java.util.Arrays;
import java.util.Collection;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
#Controller
public class UploadPianoAttivitaController extends IsfolController {
/**
*
*/
private static final long serialVersionUID = 5455170192118107020L;
private static final String UPLOAD_PAGE = "upload/upload";
private final Logger logger = LoggerFactory.getLogger(UploadPianoAttivitaController.class);
#Autowired
private FilePianoAttivitaService filePianoAttivitaService;
#RequestMapping(value = "/", method = RequestMethod.GET)
public String uploadHomePage(HttpSession session) {
logger.info("I'm home");
return goToUploadPage(session);
}
#RequestMapping(value = "/uploadInit", method = RequestMethod.GET)
public String uploadPageRedirect(HttpSession session) {
logger.info("redirect into upload");
return goToUploadPage(session);
}
#RequestMapping(value = "/uploadPiano", method = RequestMethod.POST, produces = MediaType.TEXT_PLAIN_VALUE)
#ResponseBody
public String upload(#RequestParam("files[]") MultipartFile[] files, HttpSession session) throws IWebFatalException {
logger.debug("Writing file to disk...");
try {
Collection<PianoAttivitaWrapper> piani = filePianoAttivitaService.getPianoAttivitaWrapperFromFiles(Arrays.asList(files), session.getId());
session.setAttribute(SessionConstant.PIANO_ATTIVITA_LIST_WRAPPER, piani);
} catch (IWebFatalException e) {
throw e;
} catch (Throwable t) {
logger.error(t.getLocalizedMessage(), t);
throw new IWebFatalException(t);
}
return "pianoAttivita";
}
private String goToUploadPage(HttpSession session) {
logger.debug("redirect on upload page");
sessionHelper.clearSessionPianoReference(session);
return UPLOAD_PAGE;
}
public void setFilePianoAttivitaService(FilePianoAttivitaService filePianoAttivitaService) {
this.filePianoAttivitaService = filePianoAttivitaService;
}
}
Then my abstract class for testing
package it.isfol.iweb;
import java.io.IOException;
import java.util.Properties;
import org.junit.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
#WebAppConfiguration(value = "src/main/webapp")
#ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/root-context.xml", "file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml" })
public abstract class IsfolIwebTester extends AbstractJUnit4SpringContextTests {
private final Logger logger = LoggerFactory.getLogger(IsfolIwebTester.class);
private Properties testProperties = new Properties();
#Autowired
private WebApplicationContext webapp;
protected MockMvc mockMvc;
#Before
public void setup() {
logger.debug("reading properties");
try {
testProperties.load(this.getClass().getResourceAsStream("/test-conf.properties"));
this.mockMvc = MockMvcBuilders.webAppContextSetup(webapp).build();
} catch (IOException e) {
logger.error(e.getMessage(), e);
} catch (Throwable e) {
logger.error(e.getLocalizedMessage(), e);
}
}
public String getProperty(String key) {
return testProperties.getProperty(key);
}
}
and finally the test class who extends the class above
package it.isfol.iweb.pianoattivita;
import it.isfol.iweb.IsfolIwebTester;
import org.apache.commons.io.FilenameUtils;
import org.apache.tika.io.IOUtils;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
public class FilePianoAttivitaTester extends IsfolIwebTester {
private final Logger logger = LoggerFactory.getLogger(FilePianoAttivitaTester.class);
#Test
public void testRunning() {
logger.debug("Test started");
try {
String originalFile = getProperty("test.file.pianoattivita.path");
String originalName = FilenameUtils.getName(originalFile);
byte[] content = IOUtils.toByteArray(getClass().getResourceAsStream(originalFile));
MockMultipartFile file = new MockMultipartFile("testJunit", originalName, null, content);
this.mockMvc.perform(MockMvcRequestBuilders.fileUpload("/uploadPiano").file(file)).andExpect(MockMvcResultMatchers.status().isOk()).andReturn().equals("pianoAttivita");
this.mockMvc.perform(MockMvcRequestBuilders.get("/pianoAttivita")).andExpect(MockMvcResultMatchers.view().name("upload/upload"));
} catch(Throwable t) {
logger.error(t.getLocalizedMessage(), t);
Assert.fail();
}
}
}
In the method upload of UploadPianoAttivitaController when I run Junit the param files[] contain 1 empty MultiPartFile, while when I run it on server and I upload a file from page everything is ok.

The name of your RequestParam for files must match with the MockMultipartFile name.
In your case is "files []" and in the mock is "testJunit", you can watch your HttpServletRequest params in your controller.

Try this way:
MockMultipartFile mockMultipartFile = new MockMultipartFile("file",
"OriginalName.txt",
"text/plain",
rateExceptionsFile);
mockMvc.perform(multipart(BASE_PATH + "/uploadFile")
.file(mockMultipartFile)
.contentType(MediaType.MULTIPART_FORM_DATA))
.andExpect(status().isOk());

Related

Spring test No mapping found for HTTP request with URI [/accueil] in DispatcherServlet with name ''

Hello I'm trying to test one of my class but I have this warning when i do mvn test : No mapping found for HTTP request with URI [/accueil] in DispatcherServlet with name ''.
This is strange because I have access to this page outside of the test.
here is the class that I want to test (I can access it via localhost:8080/accueil) :
package uVote.controllers;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import uVote.DAO.ScrutinDAO;
import uVote.model.Scrutin;
import uVote.model.Votant;
#Controller
#RequestMapping(value = "/accueil")
public class Accueil
{
#RequestMapping(method = RequestMethod.GET)
public String accueil(Model model,HttpServletRequest request)
{
Votant co = VerifCo.isConnecte(request);
if(co == null)
return "redirect:connexion";
else
{
request.setAttribute("votant", co);
List<Scrutin> scrutins = new ScrutinDAO().getToutScrutins();
List<Scrutin> scrutinsToShow = new ArrayList<Scrutin>();
for(Scrutin s : scrutins)
{
if(!s.estDansRegistre(co) || s.isTermine())
scrutinsToShow.add(s);
}
request.setAttribute("scrutins", scrutinsToShow);
}
return "accueil";
}
#RequestMapping(method = RequestMethod.POST)
public String deconnection(Model model,HttpServletRequest request)
{
VerifCo.deconnecteVotant(request);
return "redirect:accueil";
}
}
and here is the test case :
package uVote.controllers;
import java.util.HashMap;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import uVote.model.Votant;
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration(classes = uVote.controllers.Accueil.class)
/**
*
* #author kirua
*/
public class AccueilTest
{
#Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
#Before
public void setup()
{
DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.wac);
this.mockMvc = builder.build();
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/vues/");
viewResolver.setSuffix(".jsp");
this.mockMvc = MockMvcBuilders.standaloneSetup(new HelpController())
.setViewResolvers(viewResolver)
.build();
}
#Test
public void testVotant() throws Exception
{
HashMap<String, Object> sessionattr = new HashMap<String, Object>();
Votant vo = new Votant(1, "toto_prenom", "toto_nom", "toto_adresse", "mdp");
sessionattr.put("votant", vo);
ResultMatcher ok = MockMvcResultMatchers.status().isOk();
// ResultMatcher msg = MockMvcResultMatchers.model()
// .attribute("msg", "Spring quick start!!");
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/accueil").sessionAttrs(sessionattr);
this.mockMvc.perform(builder)
.andExpect(ok)
.andExpect(view().name("accueil"));
// .andExpect(msg);
}
}
and the HelpController :
public class HelpController extends AbstractController
{
private static Log log = LogFactory.getLog(HelpController.class);
#Override
protected ModelAndView handleRequestInternal(HttpServletRequest hsr, HttpServletResponse hsr1) throws Exception
{
log.debug("Entering HelpController.handleRenderRequestInternal()");
ModelAndView modelAndView = new ModelAndView("Help");
log.debug("Exiting HelpController.handleRenderRequestInternal() " + modelAndView);
return modelAndView;
}
}
my web.xml :
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/root-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/servlet-context.xml</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>
my servlet-context.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">
<!-- Anable du model #Controller -->
<annotation-driven />
<!-- Gère les requète d'éléments de ressource (css / js / images ...) -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Résolution des vues utilisées (renvoyées) par les controller - Rendu/Intepretation JSP -->
<beans:bean id="viewReslover" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> -->
<beans:property name="prefix" value="/vues/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="uVote.controllers" />
</beans:beans>
and my root-context :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="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.xsd">
</beans>
Do you have an idea of what is happening ? I'm a noob in java so I'm not sure where could be the problem.
Please ask if you need to see some other file.

upload file springboot Required request part 'file' is not present

I want to add an upload function to my spring boot application;
this is my upload Rest Controller
package org.sid.web;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.sid.entities.FileInfo;
#RestController
public class UploadController {
#Autowired
ServletContext context;
#RequestMapping(value = "/fileupload/file", headers = ("content-type=multipart/*"), method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<FileInfo> upload(#RequestParam("file") MultipartFile inputFile) {
FileInfo fileInfo = new FileInfo();
HttpHeaders headers = new HttpHeaders();
if (!inputFile.isEmpty()) {
try {
String originalFilename = inputFile.getOriginalFilename();
File destinationFile = new File(
context.getRealPath("C:/Users/kamel/workspace/credit_app/uploaded") + File.separator + originalFilename);
inputFile.transferTo(destinationFile);
fileInfo.setFileName(destinationFile.getPath());
fileInfo.setFileSize(inputFile.getSize());
headers.add("File Uploaded Successfully - ", originalFilename);
return new ResponseEntity<FileInfo>(fileInfo, headers, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<FileInfo>(HttpStatus.BAD_REQUEST);
}
} else {
return new ResponseEntity<FileInfo>(HttpStatus.BAD_REQUEST);
}
}
}
but when testing this in postman with inserting http://localhost:8082/fileupload/file and adding a file to the body
i got this error: "exception": org.springframework.web.multipart.support.MissingServletRequestPartException",
"message": "Required request part 'file' is not present,
This is how your request in Postman should look like:
My sample code:
application.properties
#max file and request size
spring.http.multipart.max-file-size=10MB
spring.http.multipart.max-request-size=11MB
Main Application Class:
Application.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Rest controller class:
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
#Controller
#RequestMapping("/fileupload")
public class MyRestController {
#RequestMapping(value = "/file", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody String myService(#RequestParam("file") MultipartFile file,
#RequestParam("id") String id) throws Exception {
if (!file.isEmpty()) {
//your logic
}
return "some json";
}
}
pom.xml
//...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
....
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
//...
In your method you have specified like this
#RequestParam("file"). Hence it is expecting the key to be file. It is quite evident in the exception message. Use this name in the Key field in Postman when you upload file.
More information here integration test case and file upload
I also had similar issue and was getting the error request part file not present.
But I later realized that I have this code in my application which was causing problem:
#Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new
CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(1000000000);
return multipartResolver;
}
I removed this and it started working for both RequestPart and RequestParam.
See the related issue below:
https://forum.predix.io/questions/22163/multipartfile-parameter-is-not-present-error.html
Except for other posted answers, the problem might be realated to missing multipart support for the servlet handling the request (spring's DispatcherServlet in case of Spring's app).
This can be fixed by adding multipart support to dispatcher servlet in web.xml declaration or during initialization (in case of annotation-based config)
a) web-xml based config
<web-app 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_3_0.xsd"
version="3.0">
<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/dispatcher-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<multipart-config>
<max-file-size>10485760</max-file-size>
<max-request-size>20971520</max-request-size>
<file-size-threshold>5242880</file-size-threshold>
</multipart-config>
</servlet>
</web-app>
b) for annotation-based configuration this would be following:
public class AppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) {
final AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
final ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcher", new DispatcherServlet(appContext));
registration.setLoadOnStartup(1);
registration.addMapping("/");
File uploadDirectory = new File(System.getProperty("java.io.tmpdir"));
MultipartConfigElement multipartConfigElement = new MultipartConfigElement(uploadDirectory.getAbsolutePath(), 100000, 100000 * 2, 100000 / 2);
registration.setMultipartConfig(multipartConfigElement);
} }
Then we need to provide multipart resolver which can resolve files sent as multipart-request. For annotation config this can be done in following way:
#Configuration
public class MyConfig {
#Bean
public MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
}
For xml-based spring configuration you need to add this bean to the context via tag declaration declaration:
<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver" />
Alternatively to spring's standard multipart resolver you can use implementation from commons. This way however extra dependency is required:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000000"/>
</bean>
I had similar issue with error Could not resolve parameter [0] in public org.springframework.http.ResponseEntity... Required request part 'file' is not present and tried many things but one change resolved this issue.
Had to update
// old
#RequestParam("file") MultipartFile inputFile
// new
#RequestParam(value = "file") MultipartFile inputFile
In my case, i have multi module project as;
core > api > admin
Admin and api are parent of core module.
Core/ImageController:
#RequestMapping(value = "/upload/image", method = RequestMethod.POST)
public ResponseEntity uploadBanner(#RequestParam(value = "file", required =
false) MultipartFile bannerFile){...}
AdminApplicationInitializer:
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AdminApplicationInitializer.class);
}
#Bean
public MultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
//100MB
resolver.setMaxUploadSize(100 * (long) 1024 * 1024);
return resolver;
}
#Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
factory.setMaxFileSize(DataSize.ofMegabytes(200L));
factory.setMaxRequestSize(DataSize.ofMegabytes(200L));
return factory.createMultipartConfig();
}
When i tried to upload file from api module with core service "/upload/image".
I had get an error : "Required request part 'file' is not present".
Cause of ApiInitializer had not configuration like AdminInitializer.
The Solution : i added multipartResolver() and multipartConfigElement() method to ApiApplicationInitializer.Then it worked.

Spring MVC 4 configuration not finding my controllers

Hi I am new to Spring MVC 4 I am trying to do the java configuration setup but it seems Spring is not finding my Controller it is running fine no errors on startup I can even explicitly call a jsp but if I try to call my controller it does nothing
e.g.
localhost:8080/apollo/hello.jsp <-- this renders fine if I put my JSP in the webapp directory
What I want is to call my login.jsp using my controller
My project structure is
com
+apollo
-WebAppInitializer.java
-WebConfig.java
src
+main
+webapp
-**hello.jsp**
+WEB-INF
+view
-**login.jsp**
here is my Configuration
package com.apollo;
import java.util.Locale;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.apollo")
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
#Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/view/");
resolver.setSuffix(".jsp");
return resolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/*registry.addResourceHandler("/pdfs/**").addResourceLocations("/WEB-INF/pdf/");
registry.addResourceHandler("/css/**").addResourceLocations("/WEB-INF/css/");*/
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}
}
Here is my Initializer Class
package com.apollo;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class WebAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("*.html");
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(WebConfig.class);
return context;
}
}
here is my Controller
package com.apollo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class LoginController {
#RequestMapping(value="/login")
public String greeting (Model model){
System.out.println("controller???");
model.addAttribute("greeting" , "Hello World");
return "login";
}
}
The basePackages mean the package contains the controller
Here is the problem:
#ComponentScan(basePackages = "com.apollo")
You should change to
#ComponentScan(basePackages = "com.apollo.controller")
If you put controller to modules, you should scan like this
#ComponentScan(basePackages = "com.apollo.**.controller")

how to solve BeanCreationExceptrion error?

I try to develop some server program using spring4 and jackrabbit. When i test the Controller class using JUnit, BeanCreationExceptrion error is occurs. I think this error associated with autowired variable. help me. how to solve this problem?
This is head of my Controller class.
package kr.ac.jbnu.sql.soremore.controller;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.jcr.Node;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.ac.jbnu.sql.soremore.model.RDML;
import kr.ac.jbnu.sql.soremore.model.Traceability;
import kr.ac.jbnu.sql.soremore.service.IRDMLConverter;
import kr.ac.jbnu.sql.soremore.service.IRDMLDBMgmt;
import kr.ac.jbnu.sql.soremore.service.IRDMLRDFMgmt;
import kr.ac.jbnu.sql.soremore.service.RDMLDBException;
import kr.ac.jbnu.sql.soremore.service.RDMLRDFException;
import kr.ac.jbnu.sql.soremore.service.RevisionControlException;
import kr.ac.jbnu.sql.soremore.service.rdf.RDFConverter;
import org.apache.log4j.Logger;
import org.jdom2.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
// reference
// http://crunchify.com/simplest-spring-mvc-hello-world-example-tutorial-spring-model-view-controller-tips/
#Controller
public class SoremoreController {
private static final int buffer_size = 1024;
static Logger logger = Logger.getLogger(SoremoreController.class.getName());
private static String fileName = "";
#Autowired
private ApplicationContext appContext = null;
#Autowired
private IRDMLConverter rdmlConverter = null;
#Autowired
private IRDMLRDFMgmt rdmlRDFMgmt = null;
#Autowired
private IRDMLDBMgmt rdmlDBMgmt = null;
#Autowired
private RDFConverter rdfConverter = null;
....
This is my test class.
package kr.ac.jbnu.sql.soremore.controller;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import kr.ac.jbnu.sql.soremore.model.RDML;
import kr.ac.jbnu.sql.soremore.model.Traceability;
import kr.ac.jbnu.sql.soremore.service.RDMLDBException;
import org.jdom2.Document;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#RunWith(SpringJUnit4ClassRunner.class)
//#ContextConfiguration(locations = { "classpath:/soremore-servlet.xml" })
#ContextConfiguration(locations = { "/application-config.xml" })
public class SoremoreControllerTest {
#Autowired
SoremoreController soremoreController = null;
#Test
public void storeRDML() {
// String[] hwpmlPaths = { "resource/sample_rdml/예제 1.xml",
// "resource/sample_rdml/예제 2.xml",
// "resource/sample_rdml/예제 3.xml",
// "resource/sample_rdml/예제 4.xml",
// "resource/sample_rdml/예제 5.xml",
// "resource/sample_rdml/예제 6.xml",
// "resource/sample_rdml/예제 7.xml",
// "resource/sample_rdml/예제 8.xml",
// "resource/sample_rdml/예제 9.xml",
// "resource/sample_rdml/예제 10.xml" };
//
// for (String hwpmlPath : hwpmlPaths) {
// soremoreController.storeRDML(hwpmlPath);
// }
ArrayList<RDML> rdmls = loadTestRDML();
boolean isSuccessful = false;
for (RDML rdml : rdmls) {
try {
soremoreController.storeRDML(rdml);
System.out.println();
isSuccessful = true;
} catch (Exception e) {
e.printStackTrace();
isSuccessful = false;
}
}
Assert.assertTrue(isSuccessful);
}
#Test
public void storeRDMLWithTraceability() throws IOException {
List<RDML>rdmls = null ;
String previousRDMLId = "xxx";
for (RDML rdml : rdmls) {
soremoreController.storeRDMLWithTraceability(rdml,
previousRDMLId, TraceabilityTypes.satisfy);
}
}
#Test
public void updateRDMLWithTraceability() {
String previousRDMLId1 = "xxx";
String previousRDMLId2 = "xxx";
String updatedTraceability = soremoreController.updateRDMLTraceability(
previousRDMLId1, previousRDMLId2, TraceabilityTypes.satisfy);
}
#Test
public void deleteRDMLWithTraceability() {
String previousRDMLId1 = "xxx";
String previousRDMLId2 = "xxx";
String removedTraceability = soremoreController.deleteRDMLTraceability(
previousRDMLId1, previousRDMLId2);
}
#Test
public void searchRDML() {
String rdmlKeyWord = "abc";
ArrayList<RDML> rdmls = soremoreController.searchRDML(rdmlKeyWord);
for (RDML rdml : rdmls) {
System.out.println(rdml);
}
}
#Test
public void searchRDML0() {
String rdmlKeyWord = "def";
ArrayList<RDML> rdmls = soremoreController.searchRDML(rdmlKeyWord);
for (RDML rdml : rdmls) {
System.out.println(rdml);
}
}
#Test
public void searchRDML1() {
String rdmlKeyWord = "2차년도계획서";
ArrayList<RDML> rdmls = soremoreController.searchRDML(rdmlKeyWord);
for (RDML rdml : rdmls) {
System.out.println(rdml);
}
}
#Test
public void getRDML() {
String rdmlID = "abc";
RDML rdml = soremoreController.getRDML(rdmlID);
}
#Test
public void getParentIDs() {
String rdmlID = "abcd";
ArrayList<String> parentIDs = soremoreController.getParentIDs(rdmlID);
for (String string : parentIDs) {
}
}
#Test
public void getChildIDs() {
String rdmlID = "abcd";
ArrayList<String> childIDs = soremoreController.getChildIDs(rdmlID);
for (String string : childIDs) {
}
}
public void getDirectLinkedTraceability() {
String rdmlID = "abcd";
ArrayList<Traceability> linkedTraceabilities = soremoreController
.getDirectLinkedTraceability(rdmlID);
for (Traceability traceability : linkedTraceabilities) {
}
}
public ArrayList<RDML> loadTestRDML() {
ArrayList<RDML> rdmls = new ArrayList<RDML>();
String xmlSource = "resource/sample_rdml";
File sourceDir = new File(xmlSource);
File[] sourceFiles = sourceDir.listFiles();
for (File file : sourceFiles) {
RDML rdml = new RDML();
rdml.setRdmlAsDocument(createDocument(file));
rdmls.add(rdml);
}
return rdmls;
}
private Document createDocument(File rdmlPathAsFile) {
SAXBuilder jdomBuilder = new SAXBuilder();
Document jdomDocument = null;
try {
jdomDocument = jdomBuilder.build(rdmlPathAsFile);
} catch (JDOMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jdomDocument;
}
}
This is my spring configuration 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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
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">
<context:component-scan base-package="kr.ac.jbnu.sql.soremore" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
<property name="contentType" value="text/html; charset=UTF-8" />
</bean>
<!-- for file upload -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- setting maximum upload size -->
<property name="maxUploadSize" value="20000000" />
</bean>
</beans>
This is head of class of one variable.
package kr.ac.jbnu.sql.soremore.service.rdml;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.ValueFormatException;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.jcr.version.Version;
import javax.jcr.version.VersionException;
import javax.jcr.version.VersionHistory;
import javax.jcr.version.VersionIterator;
import javax.jcr.version.VersionManager;
import javax.xml.parsers.ParserConfigurationException;
import kr.ac.jbnu.sql.soremore.controller.SoremoreController;
import kr.ac.jbnu.sql.soremore.model.RDML;
import kr.ac.jbnu.sql.soremore.service.IRDMLDBMgmt;
import kr.ac.jbnu.sql.soremore.service.RDMLDBException;
import kr.ac.jbnu.sql.soremore.service.RevisionControlException;
import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.log4j.Logger;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.output.XMLOutputter;
import org.springframework.stereotype.Service;
#Service
public class RDMLDBMgmtImpl implements IRDMLDBMgmt {
static Logger logger = Logger.getLogger(SoremoreController.class.getName());
static private int docNumber = 0;
private Repository repository;
private Session session;
....
This is stacktrace.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'kr.ac.jbnu.sql.soremore.controller.SoremoreControllerTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: kr.ac.jbnu.sql.soremore.controller.SoremoreController kr.ac.jbnu.sql.soremore.controller.SoremoreControllerTest.soremoreController; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [kr.ac.jbnu.sql.soremore.controller.SoremoreController] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1204)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:385)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:82)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:199)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:251)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:253)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:216)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:82)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:60)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:67)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:162)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: kr.ac.jbnu.sql.soremore.controller.SoremoreController kr.ac.jbnu.sql.soremore.controller.SoremoreControllerTest.soremoreController; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [kr.ac.jbnu.sql.soremore.controller.SoremoreController] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:555)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 26 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [kr.ac.jbnu.sql.soremore.controller.SoremoreController] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1261)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1009)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:904)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:527)
... 28 more
In order for Spring to autowire the SoremoreController field in your test case it needs a bean definition in the ApplicationContext for a bean of that type. That means you need to component-scan the package (or a parent package) where the SoremoreController is defined in the xml file you point out in the ContextConfiguration annotation.
Note that all autowired fields in SoremoreController instance must also have corresponding beans defined in the ApplicationContext, otherwise Spring will not be able to create that instance, causing your test to fail with stacktraces similar to the one you posted (but always explicitly pointing out - towards the end - the root cause of the problem).

Status expected:<200> but was:<404> in spring test

I have this class:
package controllers;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.HashSet;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.ui.Model;
import org.springframework.web.context.WebApplicationContext;
import com.epam.hhsystem.model.candidate.Candidate;
import com.epam.hhsystem.services.CandidateService;
import com.epam.hhsystem.web.controllers.CandidateMenuController;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.context.junit4.*;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.request.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.hamcrest.Matchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
#ContextConfiguration(locations = { "classpath:/test/BeanConfig.xml" })
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
public class CandidateControllerTest {
#Mock(name = "candidateService")
private CandidateService candidateService;
#InjectMocks
private CandidateMenuController candidateMenuController = new CandidateMenuController();
#Autowired
WebApplicationContext wac;
MockMvc mockMvc;
#Before
public void before() {
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).dispatchOptions(true).build();
}
#Test
public void testgoToCandidateMenuMockMvc() throws Exception {
//MockHttpServletRequestBuilder request = MockMvcRequestBuilders.get("/goToCandidateMenu");
MockHttpServletRequestBuilder request = MockMvcRequestBuilders.get("/goToCandidateMenu");
ResultActions result = mockMvc.perform(request);
result.andExpect(status().isOk());
}
}
When I execute it I see:
java.lang.AssertionError: Status expected:<200> but was:<404>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:89)
at org.springframework.test.web.servlet.result.StatusResultMatchers$5.match(StatusResultMatchers.java:549)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:141)
at controllers.CandidateControllerTest.testgoToCandidateMenuMockMvc(CandidateControllerTest.java:104)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Controller code:
#Controller
public class CandidateMenuController extends AbstractController {
...
#RequestMapping("/goToCandidateMenu")
public String goToCandidateMenu() {
return "candidateMenu";
}
...
}
Can you help me to fix my problem?
UPDATE
BeanConfig.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- Включаем опцию использования конфигурационных аннотаций (#Annotation-based configuration)-->
<context:annotation-config />
<context:component-scan base-package="com.epam.hhsystem.jpa" />
<context:component-scan base-package="com.epam.hhsystem.services" />
<!-- Файл с настройками ресурсов для работы с данными (Data Access Resources) -->
<import resource="data.xml" />
</beans>
data.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- Настраивает управление транзакциями с помощью аннотации #Transactional -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Менеджер транзакций -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- Непосредственно бин dataSource -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
p:url="jdbc:sqlserver://10.16.9.52:1433;databaseName=hhsystemTest;"
p:username="userNew"
p:password="Pass12345" />
<!-- Настройки фабрики сессий Хибернейта -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:test/hibernate.cfg.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
<!-- <prop key="hibernate.hbm2ddl.auto">create-drop</prop> -->
</props>
</property>
</bean>
</beans>
Your test setup is wrong you aren't initializing the MockMvc correctly and that is al clearly in the reference guide. FIrst of all you have twice the initializing code and you aren't assing the result of the call to the build method. So you are basically left with an empty MockMvc object.
#Before
public void before() {
MockitoAnnotations.initMocks(this);
MockMvcBuilders.webAppContextSetup(this.wac).dispatchOptions(true).build();
MockMvcBuilders.webAppContextSetup(this.wac).dispatchOptions(true).build();
}
Should be
#Before
public void before() {
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).dispatchOptions(true).build();
}
As stated this is all explained in the reference guide.
I believe you just haven't enabled <mvc:annotation-driven> in your beanconfig.xml and so your #Controller classes just aren't being registered.
Add this
<mvc:annotation-driven></mvc:annotation-driven>
In my case, I was missing the below annotation and was getting this error.
#WebMvcTest(UserStatsController.class)
public class UserStatsControllerTest {
..
}
Note that the class of the controller and NOT the test.
Make sure as well if you load other class using #ContextConfiguration(NOT the test) not load test class.
This is my working solution. Hope it helps.
#RunWith(SpringRunner.class)
#SpringBootTest(classes = Application.class)
#WebAppConfiguration
public class SimpleTest {
private MockMvc mockMvc;
#Autowired
private WebApplicationContext webApplicationContext;
#Before
public void setup() throws Exception {
mockMvc = webAppContextSetup(webApplicationContext)
.build();
}
#Test
public void test() throws Exception {
mockMvc.perform(get("/simple")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is(200));
}
}
In the case that you make a really stupid "going to fast for your own good" typo like I did, make sure that your controller test class does NOT have the same name as the controller class itself. Most people know this, but you can get into this same error condition the names are identical, and it may not my immediately obvious why. To clarify further, make sure you DO NOT DO THIS:
Controller name: MyController
Test class name: MyController
This can cause your MockMvc tests to fail with status 404... which is not very obvious.
Naming [obviously] should be more like:
Controller name: MyController
Test class name: MyControllerTest
I added this annotations to configuration class and work it:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(loader = AnnotationConfigWebContextLoader.class)
#WebAppConfiguration
public class ResourceTest {
...
#Configuration
#EnableWebMvc
#ComponentScan( basePackages = { "..." } )
static class ContextConfiguration {
}
}
My problem was I did not have #ComponentScan() it was pretty embarrassing.
It was also hard to find.I,myself overlooked my SpringBootApplication.
Following is what i did in spring mvc which worked fine (explained as unable to find direct reference)
Controller class as folowing
package rndpurpose.controller;
#RestController
#RequestMapping("/springmvc")
public class urlController {
#CrossOrigin
#RequestMapping(value = "managepostReq", method = RequestMethod.POST, headers = "Accept=application/json")
public Map<String, Object> managepostReq()
{
Map<String, Object> response = new HashMap<>();
//System.out.println(data);
response.put("status", true);
return response;
}
}
Inside rndpurpose.text (package) > created package related to same as my #ComponentScan in WebConfig.java created test class
package rndpurpose.test;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.json.JSONObject;
import org.junit.Test;
import org.springframework.core.annotation.Order;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import junit.framework.Assert;
public class UrlcontrollerTest extends JunitAbstract {
#Test
#Order(1)
public void firsttestcase() throws Exception {
/*jai ganesha*/
try {
JSONObject jsonGetData = new JSONObject();
jsonGetData.put("username", "name");
ResultActions resultActions = postRequest("/springmvc/managepostReq", jsonGetData.toString());
MvcResult mvcResult = resultActions.andExpect(status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn();
JSONObject reqResponse = new JSONObject(mvcResult.getResponse().getContentAsString());
System.out.println(reqResponse);
} catch (Exception e) {
System.err.println("ERROR"+ e);
}
}
}
And JunitAbstract for handling req
package rndpurpose.test;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.Charset;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.util.MultiValueMap;
import org.springframework.web.context.WebApplicationContext;
import rndpurpose.config.WebConfig;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = WebConfig.class)
#WebAppConfiguration
#ComponentScan(basePackages="rndpurpose")
public abstract class JunitAbstract {
public static final MediaType APPLICATION_JSON_UTF8 = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
private MockMvc mockMvc;
#Autowired
public WebApplicationContext wac;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
public ResultActions postRequest(String url, String bodyData) {
ResultActions resultActions = null;
try {
System.out.println(url);
resultActions = mockMvc.perform(post(url).contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON).content(bodyData));
}
catch (InvocationTargetException e) {
e.getCause().printStackTrace();
}
catch (Exception e) {
System.err.println("Error while executing post req "+ e);
}
return resultActions;
}
public ResultActions getRequest(String url) {
ResultActions resultActions = null;
try {
resultActions = this.mockMvc.perform(get(url)).andDo(print());
} catch (Exception e) {
System.err.println("Error while executing test case for get"+ e);
}
return resultActions;
}
public ResultActions multipartFileUpload(String url, MultiValueMap<String, String> bodyMap,
MockMultipartFile... files) {
ResultActions resultActions = null;
try {
MockMultipartHttpServletRequestBuilder builder = multipart(url);
addMultipartFiles(builder, files);
if (bodyMap != null)
builder.params(bodyMap);
resultActions = mockMvc.perform(builder);
} catch (Exception e) {
System.err.println("Error in multipartFileUpload "+ e);
}
return resultActions;
}
private void addMultipartFiles(MockMultipartHttpServletRequestBuilder builder, MockMultipartFile... files) {
if (files != null) {
for (MockMultipartFile file : files) {
builder.file(file);
}
}
}
}
and pom looks like this
<!-- test starts -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.2.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.23.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>1.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.8.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.19</version>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.0.0</version>
</dependency>
<!-- test ends -->
In my case, I was missing #ComponentScan("my.package.*") on MyApplication class because my controller was in a different package than MyApplication class.
Do check the debugger tick mark in debugging mode. if the component is getting scanned it will show as Tick mark else it will not.
Experienced similar error when my controllers were not loaded , in case of spring mvc with .xml based dispatcher servlet i was able to fix it by adding #ContextConfiguration
as following
Has a bean to connect db
#EnableWebMvc
public class WebConfig {
private static final Logger LOGGER = Logger.getLogger(WebConfig.class);
#Bean
public CommonsMultipartResolver multipartResolver() {
final CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSize(20971520);
resolver.setMaxInMemorySize(1048576);
return resolver;
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl("jdbc:postgresql://192.168.2.29:5432/trintiygisenterprise");
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUsername("postgres");
dataSource.setPassword("track#123");
return dataSource;
}
#Bean
public Connection getConnectionObject() {
Connection con = null;
try {
Class.forName("org.postgresql.Driver");
con = DriverManager.getConnection("jdbc:postgresql://localhost:5432/t26",
"postgres", "track#123");
System.out.println("====================CONNECTED TO DB================ "+con);
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
return con;
}
#Bean
#Autowired
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
and it will be scanned in springrest-servlet.xml
<context:component-scan base-package="com" />
<mvc:annotation-driven />
<!-- <mvc:resources mapping="/*" location="/" />-->
<mvc:default-servlet-handler/>
<bean class="com.config.WebConfig"/>
</beans>
and the web.xml
<servlet>
<servlet-name>springrest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springrest</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Controller lookes like this
#RestController
#RequestMapping("/api")
public class bootsrapController {
/**
#GetMapping("/second")
**/
#RequestMapping(value = "second", method = RequestMethod.GET, headers =
"Accept=application/json")
public Map<String, Object> second()
{
Map<String, Object> result = new HashMap<>();
result.put("second", true);
result.put("status", true);
return result;
}
}
Testcontroller as follows
public class UrlcontrollerTest extends JunitAbstract {
#Test
#Order(1)
public void unittestcreatelayergroup(){
try {
System.out.println("Running test");
final ResultActions resultActions = getRequest("/api/second");
System.out.println(resultActions);
final MvcResult mvcResult = resultActions
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(jsonPath("status", is(true)))
.andReturn();
}
catch (final Exception e) {
LOGGER.error(e.getStackTrace());
}
}
and unit test for get req as follows
#ContextConfiguration("file:src/main/webapp/WEB-INF/springrest-servlet.xml")
#WebAppConfiguration
public abstract class JunitAbstract {
private static final Logger LOGGER = Logger.getLogger(JunitAbstract.class);
private MockMvc mockMvc;
#Autowired
public WebApplicationContext wac;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
public ResultActions getRequest(String url) {
LOGGER.info("sending req--------: "+url);
ResultActions resultActions = null;
try {
resultActions = this.mockMvc.perform(get(url)).andDo(print());
} catch (Exception e) {
LOGGER.error("Error while executing test case for get"+ e);
}
return resultActions;
}
thanks to #tunguski answer too enter link description here

Categories

Resources