Get nullPoint when using NamedParameterJdbcTemplate - spring-mvc

Depending on project's requirement, we want to change from JdbcTemplate into NamedParameterJdbcTemplate in database handling. But I got null point error when I test my coding. I'm sure the error has occurred because of my configuration, but I could not resolve it.
Config
#Value("${spring.datasource.driver-class-name}")
protected String driver;
#Value("${spring.datasource.url}")
protected String url;
#Value("${spring.datasource.username}")
protected String user;
#Value("${spring.datasource.password}")
protected String pass;
#Bean
public DataSource dataSource(){
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(user);
dataSource.setPassword(pass);
dataSource.setTestOnBorrow(true);
dataSource.setTestOnReturn(true);
dataSource.setTestWhileIdle(true);
return dataSource;
}
#Bean
public JdbcTemplate jdbcTemplate(){
return new JdbcTemplate(dataSource());
}
#Bean
public NamedParameterJdbcTemplate namedParameterJdbcTemplate(){
return new NamedParameterJdbcTemplate(dataSource);
}
DaoImpl
#Repository
public class DAOImpl implements DAO {
#Autowired
private NamedParameterJdbcTemplate jdbcTemplate;
#Override
public List<Type> findAllType() {
String sql = "select * from type";
RowMapper<Type> rm = new TypeRowMapper();
List<Type> list = jdbcTemplate.query(sql, rm);
return list;
}
}
Test
public class Test {
#Autowired
protected DAOImpl dao;
public static void main(String[] args) {
List<Type> list = new ArrayList<Type>();
Test test = new Test();
System.out.println(test.dao);
list = test.dao.findAllType();
for(Type type : list){
System.out.println(type.getName());
}
}
}
Stacktrace
null
Exception in thread "main" java.lang.NullPointerException
at com.example.dao.Test.main(Test.java:18)

Related

How to preserve HttpServletRequest autowiring when testing with SpringMVC Mockito and PowerMockito

Hi I'm trying to write some tests with Mockito and PowerMockito (I need to mock private methods) for a rest service written with SpringMVC and I'm facing the following issue
This is the semplified version of the controller
#Controller
#RequestMapping(value = "/test")
public class SimpleController {
#Autowired
private HttpServletRequest httpRequest;
#RequestMapping(value = "/simpleservice", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
#ResponseBody
public SimpleServiceResponse simpleService(#RequestBody SimpleServiceRequest simpleServiceRequest, HttpServletRequest httpServletRequest) {
SimpleServiceResponse simpleServiceResponse=new SimpleServiceResponse(simpleServiceRequest.getValue());
httpRequest.getHeader("Header");
return simpleServiceResponse;
}
}
and this is the correspoding test class
#WebAppConfiguration
#RunWith(PowerMockRunner.class)
#PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:WebApplicationContext.xml","classpath:SimpleApplicationContext.xml"})
#PrepareForTest(WebController.class)
#TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
public class TestSimpleControllerMockito {
private Logger logger = LoggerFactory.getLogger(TestSimpleControllerMockito.class.getName());
private ObjectMapper objectMapper= new ObjectMapper();
#InjectMocks
private SimpleController controller;
#Test
public void testSimpleService() throws Exception {
MockitoAnnotations.initMocks(this);
SimpleService mockedSimple = mock(SimpleService.class);
when(mockedSimple.doSimpleService(any(SimpleServiceRequest.class))).thenReturn(new SimpleServiceResponse("MockMock"));
SimpleController mockedController=PowerMockito.spy(controller);
SimpleServiceRequest simpleServiceRequest= new SimpleServiceRequest("ciao");
String requestAsStr=objectMapper.writeValueAsString(simpleServiceRequest);
MockMvc mMockMvc=MockMvcBuilders.standaloneSetup(mockedController).build();
MvcResult result= mMockMvc.perform(post("/test/simpleservice").content(requestAsStr).contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andReturn();
String content = result.getResponse().getContentAsString();
SimpleServiceResponse simpleServiceResponse=objectMapper.readValue(content,SimpleServiceResponse.class);
Assert.assertEquals("MockMockMockedSessionManager",simpleServiceResponse.getValue());
}
}
When running the test case I got a NullPointerEception on httpRequest.getHeader("Header");
My guess is that using the #InjectMocks annotation and then using
SimpleController mockedController=PowerMockito.spy(controller);
is the cause of the NullPointerException. I don't know how to preserve the #Autowire annotation processing on the controller Object. I already found a workaround, but it requires to write some redundant code.
Is there a way to make the #autowired annotation work?
Thanks a lot.
P.S.
the SimpleServiceXXX classes are like this one:
public class SimpleServiceResponse {
private String value;
public SimpleServiceResponse() {
}
public SimpleServiceResponse(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}

Data fetching from database on each hit not from the cache

This is the Application.java class
#Configuration
#SpringBootApplication
//#EnableGlobalMethodSecurity(prePostEnabled=true)
#EnableTransactionManagement
#EnableCaching
#EnableJpaRepositories(basePackages="om.gov.moh.irs.dao.repos",repositoryImplementationPostfix="CustomImpl")
public class Application extends SpringBootServletInitializer {
#Autowired
Environment env;
#Bean
#ConfigurationProperties("spring.datasource")
public ComboPooledDataSource dataSource() {
return new ComboPooledDataSource();
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasenames("messages"); // name of the resource bundle
source.setUseCodeAsDefaultMessage(true);
return source;
}
#Bean
MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
factory.setMaxFileSize(env.getProperty("multipart.maxFileSize"));
factory.setMaxRequestSize(env.getProperty("multipart.maxRequestSize"));
return factory.createMultipartConfig();
}
}
This is the dto class which Im trying to cache.
public class PaginationDto implements Serializable {
private static final long serialVersionUID = 1L;
public Integer totalRecords;
public List<?> paginatedList;
//constructor and getter setter here
}
Controller class
#RequestMapping(value="categories", method=RequestMethod.POST, produces = { "application/json" })
public #ResponseBody ResultDecorator searchCategories(#RequestBody CategoryDto categoryDto) int pageSize, #RequestParam("sort") String sortOrder) throws BusinessException{
return handler.resolveResult(categoryService.searchCategory(categoryDto), OperationEnum.SEARCH);
}
Service class where #cacheable is defined.
#Override
#Cacheable("category")
public PaginationDto searchCategory(CategoryDto categoryDto) throws CategoryException {
System.out.println("#######category");
PaginationDto paginationDtoResponse = null;
paginationDtoResponse = categoryRepoCustom.fetchCategories(categoryDto);
return paginationDtoResponse;
}
Defined ehcache.xml file
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.ehcache.org/ehcache.xsd"
updateCheck="true" monitoring="autodetect" dynamicConfig="true">
<cache name="category"
maxElementsInMemory="100" eternal="false"
overflowToDisk="false"
timeToLiveSeconds="30000" timeToIdleSeconds="0"
memoryStoreEvictionPolicy="LFU" transactionalMode="off">
</cache>
</ehcache>
On hitting this http://localhost:9190/isa/categories each time console log is printing, which means data is not fetching from the cache.

How to use Jackson to deserialise list in java?

My Java Class is
public class User {
private List<UserInfo> userInfoList;
public class UserInfo {
private String id;
}
}
Let's assume it has getter, setter method.
json is
{"userInfoList" : [{"id":"a", "id":"b"}]}
I tried to deserialize it like below.
objectMapper.readValue(json, User.class);
But it throws error.
Can not construct instance of User$UserInfoList: no suitable constructor found
How to deserialize it?
I think you should make UserInfo static. Jackson cannot construct the UserInfo class.
I tried with that change and it works for me :
public class User {
private List<UserInfo> userInfoList;
public static class UserInfo {
private String id;
public UserInfo() {
super();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
public List<UserInfo> getUserInfoList() {
return userInfoList;
}
public void setUserInfoList(List<UserInfo> userInfoList) {
this.userInfoList = userInfoList;
}
}
And :
public class App {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
User.UserInfo ui1 = new User.UserInfo();
ui1.setId("a");
User.UserInfo ui2 = new User.UserInfo();
ui2.setId("b");
List<User.UserInfo> userInfoList = new ArrayList<User.UserInfo>();
userInfoList.add(ui1);
userInfoList.add(ui2);
User user = new User();
user.setUserInfoList(userInfoList);
System.out.println(mapper.writeValueAsString(user));
user = mapper.readValue(mapper.writeValueAsString(user), User.class);
}
}

#Context WebConfig not injected when using JerseyTest 2.0

I have a simple resource like:
#Path("/")
public class RootResource {
#Context WebConfig wc;
#PostConstruct
public void init() {
assertNotNull(wc);
}
#GET
public void String method() {
return "Hello\n";
}
}
Which I am trying to use with JerseyTest (2.x, not 1.x) and the GrizzlyTestContainerFactory.
I can't work out what I need to do in terms of config to get the WebConfig object injected.
I solved this issue by creating a subclass of GrizzlyTestContainerFactory and explicitly loading the Jersey servlet. This triggers the injection of the WebConfig object. The code looks like this:
public class ExtendedGrizzlyTestContainerFactory implements TestContainerFactory {
private static class GrizzlyTestContainer implements TestContainer {
private final URI uri;
private final ApplicationHandler appHandler;
private HttpServer server;
private static final Logger LOGGER = Logger.getLogger(GrizzlyTestContainer.class.getName());
private GrizzlyTestContainer(URI uri, ApplicationHandler appHandler) {
this.appHandler = appHandler;
this.uri = uri;
}
#Override
public ClientConfig getClientConfig() {
return null;
}
#Override
public URI getBaseUri() {
return uri;
}
#Override
public void start() {
if (LOGGER.isLoggable(Level.INFO)) {
LOGGER.log(Level.INFO, "Starting GrizzlyTestContainer...");
}
try {
this.server = GrizzlyHttpServerFactory.createHttpServer(uri, appHandler);
// Initialize and register Jersey Servlet
WebappContext context = new WebappContext("WebappContext", "");
ServletRegistration registration = context.addServlet("ServletContainer", ServletContainer.class);
registration.setInitParameter("javax.ws.rs.Application",
appHandler.getConfiguration().getApplication().getClass().getName());
// Add an init parameter - this could be loaded from a parameter in the constructor
registration.setInitParameter("myparam", "myvalue");
registration.addMapping("/*");
context.deploy(server);
} catch (ProcessingException e) {
throw new TestContainerException(e);
}
}
#Override
public void stop() {
if (LOGGER.isLoggable(Level.INFO)) {
LOGGER.log(Level.INFO, "Stopping GrizzlyTestContainer...");
}
this.server.stop();
}
}
#Override
public TestContainer create(URI baseUri, ApplicationHandler application) throws IllegalArgumentException {
return new GrizzlyTestContainer(baseUri, application);
}
Notice that the Jersey Servlet configuration is being loaded from the ApplicationHandler that is passed in as a parameter using the inner Application object's class name (ResourceConfig is a subclass of Application). Therefore, you also need to create a subclass of ResourceConfig for this approach to work. The code for this is very simple:
package com.example;
import org.glassfish.jersey.server.ResourceConfig;
public class MyResourceConfig extends ResourceConfig {
public MyResourceConfig() {
super(MyResource.class);
}
}
This assumes the resource you are testing is MyResource. You also need to override a couple of methods in your test like this:
public class MyResourceTest extends JerseyTest {
public MyResourceTest() throws TestContainerException {
}
#Override
protected Application configure() {
return new MyResourceConfig();
}
#Override
protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
return new ExtendedGrizzlyTestContainerFactory();
}
#Test
public void testCreateSimpleBean() {
final String beanList = target("test").request().get(String.class);
Assert.assertNotNull(beanList);
}
}
Finally, for completeness, here is the code for MyResource:
#Path("test")
public class MyResource {
#Context WebConfig wc;
#PostConstruct
public void init() {
System.out.println("WebConfig: " + wc);
String url = wc.getInitParameter("myparam");
System.out.println("myparam = "+url);
}
#GET
#Produces(MediaType.APPLICATION_JSON)
public Collection<TestBean> createSimpleBean() {
Collection<TestBean> res = new ArrayList<TestBean>();
res.add(new TestBean("a", 1, 1L));
res.add(new TestBean("b", 2, 2L));
return res;
}
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public TestBean roundTrip(TestBean s) {
return s;
}
}
The output of running the test shows that the WebConfig is loaded and the init param is now available:
WebConfig: org.glassfish.jersey.servlet.WebServletConfig#107d0f44
myparam = myvalue
The solution from #ametke worked well but wasn't picking up my ExceptionMapper classes. To solve this I simplified the start() method to:
#Override
public void start() {
try {
initParams.put("jersey.config.server.provider.packages", "my.resources;my.config");
this.server = GrizzlyWebContainerFactory.create(uri, initParams);
} catch (ProcessingException | IOException e) {
throw new TestContainerException(e);
}
}
This was based on Problems running JerseyTest when dealing with HttpServletResponse

Spring MVC doesn't handle the error came from hibernate validator

I create form and controller this form have some validation constrains using Hibernate validator. I face problem when starting test the validation constrains but I got Blue Exception page with the attributemodel with the rejected.
This the configuration
#Configuration
#ComponentScan(basePackages = {"com.whatever.core.web"})
#EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurationSupport {
private static final String MESSAGE_SOURCE = "/WEB-INF/classes/messages";
private static final String TILES = "/WEB-INF/tiles/tiles.xml";
private static final String VIEWS = "/WEB-INF/views/**/views.xml";
private static final String RESOURCES_HANDLER = "/resources/";
private static final String RESOURCES_LOCATION = RESOURCES_HANDLER + "**";
#Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping requestMappingHandlerMapping = super.requestMappingHandlerMapping();
requestMappingHandlerMapping.setUseSuffixPatternMatch(false);
requestMappingHandlerMapping.setUseTrailingSlashMatch(false);
return requestMappingHandlerMapping;
}
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJacksonHttpMessageConverter());
}
#Bean(name = "messageSource")
public MessageSource configureMessageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename(MESSAGE_SOURCE);
messageSource.setCacheSeconds(5);
return messageSource;
}
#Bean
public TilesViewResolver configureTilesViewResolver() {
return new TilesViewResolver();
}
#Bean
public TilesConfigurer configureTilesConfigurer() {
TilesConfigurer configurer = new TilesConfigurer();
configurer.setDefinitions(new String[] {TILES, VIEWS});
return configurer;
}
#Override
public Validator getValidator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(configureMessageSource());
return validator;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(RESOURCES_HANDLER).addResourceLocations(RESOURCES_LOCATION);
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
and the controller here
if(result.hasErrors()){
return null; OR "view name"
}
User user = new User();
user.setUsername(userModel.getUsername());
user.setFirstName(userModel.getFirstName());
user.setLastName(userModel.getLastName());
user.setGender(userModel.getGender());
user.setLocation(userModel.getLocation());
user.setPassword(passwordEncoder.encodePassword(userModel.getPassword(),null));
userRepository.save(user);
doAutoLogin(userModel.getUsername(),userModel.getPassword(),request);
return "redirect:/home";
NOTE: I use springMVC, spring security, tiles, and hibernate validator
I used SpringMVC with hibernate validator with XML configuration and portal environment and work fine I don't know what the wrong here!!
I Found the issue! the signature of the method controller should be like this
public String signup(#ModelAttribute("userModel") #Valid SignupForm userModel,BindingResult result,HttpServletRequest request,HttpServletResponse response,ModelMap model)
as what I read in sprinsource forum, the BindingResult should follow the modelAttribute and work find. I didn't find any official documentation for this but its work now.
to see the thread of springsource forum check this link http://forum.springsource.org/showthread.php?85815-BindException-Thrown-on-bind-errors-(instead-of-returning-errors-to-controller-method

Resources