I need to set cookie and store cookie - key, value and timestamp in MYSQL.
Hence, i have a CookieUtil.java to set(addCookie) and get cookie. Then I created a CookieEntity.java and mapped it with a DAO layer - interface and implementation. I have nullpointer at int noOfRows = namedParameterJdbcTemplate.update(SQL,namedParameters);.
It seems namedParameterJdbcTemplate is null. But I really can't figure out why?
CookieEntity.java
import java.sql.Timestamp;
public class EWPCookieEntity {
private String key;
private String value;
private Timestamp timeStamp;
//.... setters and getters
}
CookieDao.java interface
public boolean saveCookie(CookieEntity reqCookie);
CookieDaoImpl.java
package com......dao.impl;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;
import com......CookieDao;
import com......CookieEntity;
#Repository
public class CookieDaoImpl implements CookieDao{
#Autowired(required=false)
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
private String FETCH_USER_DETAILS_QUERY = "fetch.user.query";
private static Logger logger = Logger.getLogger(CookieDaoImpl.class.getName());
#Override
public boolean saveCookie(CookieEntity reqCookie) {
String SQL = "insert into cookie_details(KEY, VALUE, TIMESTAMP) VALUES (:key, :value, :timeStamp)";
Map<String,String > namedParameters = new HashMap<String, String>();
namedParameters.put("key", reqCookie.getKey());
namedParameters.put("value", reqCookie.getValue());
//namedParameters.put("timeStamp", reqCookie.getTimeStamp());
int noOfRows = namedParameterJdbcTemplate.update(SQL,namedParameters);
System.out.println(noOfRows);
logger.info("Cookie Details Saved: [ " + reqCookie.toString() + " ]");
return noOfRows > 0 ? true : false;
}
#Override
public List<CookieEntity> getCookieValue(String key) {
return null;
}
#Override
public int deleteCookie(String key) {
return 0;
}
#SuppressWarnings("unused")
private void mapFromCookieDetailsResultSet(final CookieEntity cookieEntity, final ResultSet resultSet) {
try {
cookieEntity.setKey(resultSet.getString("KEY"));
cookieEntity.setValue(resultSet.getString("VALUE"));
cookieEntity.setTimeStamp(resultSet.getTimestamp("TIMESTAMP"));
} catch (SQLException se) {
if (logger.isDebugEnabled()) {
logger.debug(
"**** Class UserDetailsDaoImpl **** Method mapFromUserDetailsResultSet **** SQLException Occured : "
+ se.getMessage());
}
} catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug(
"**** Class UserDetailsDaoImpl **** Method mapFromUserDetailsResultSet **** Exception Occured : "
+ e.getMessage());
}
}
}
/**
* #param namedParameterJdbcTemplate the namedParameterJdbcTemplate to set
*/
public void setNamedParameterJdbcTemplate(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
}
}
My stacktrace is:
SEVERE: Servlet.service() for servlet [SimulatorServlet] in context with path [/abc]
threw exception [Request processing failed; nested exception
java.lang.NullPointerException] with root cause
java.lang.NullPointerException
at com....CookieDaoImpl.saveCookie(CookieDaoImpl.java:36)
at com......LoginController.doLogin(LoginController.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
My root_context.xml
<!-- JdbcTemplate -Starts -->
<bean id = "jdbcTemplate" class = "org.springframework.jdbc.core.JdbcTemplate">
<property name="fetchSize" value = "100"/>
<property name="dataSource" ref = "appDataSource"/>
</bean>
<!-- JdbcTemplate -Ends -->
<!-- NamedParameterJdbcTemplate -Starts -->
<bean id = "namedParameterJdbcTemplate" class = "org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="jdbcTemplate"/>
</bean>
<!-- NamedParameterJdbcTemplate -ends -->
You can add <context:annotation-config /> in your root_context.xml to get #Autowired working.
Or you add <context:component-scan base-package="your.package"/> in root_context.xml if you plan to use annotations like #Service, #Component etc. The latter one has the first one already included.
Related
In spring boot using Jsp, I have created a Employee management System where we can add,update and delete employee. but the problem is when I try to update the values in table I get NumberFormatException error. I couldn't add Employee Details also so, I had fetch values into table from database. the problem is in DAO.Class where I should do some changes. I've tried many ways but nothing works for me. so, please give me a solution for this problem.
EmployeeDao class
package net.javaguides.ems.controller;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import net.javaguides.ems.entity.Employee;
#Service()
public class EmployeeDao
{
#Autowired
JdbcTemplate jdbcTemplate;
/*
* public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate =
* jdbcTemplate; }
*/
public List<Employee> getAllEmployees()
{
//List<Map<String,String>> data = new ArrayList<Map<String, String>>();
return jdbcTemplate.query("select * from employee", new RowMapper<Employee>()
{
public Employee mapRow(ResultSet rs, int row) throws SQLException
{
Employee emp = new Employee();
emp.setId(rs.getLong("id"));
emp.setFirstName(rs.getString("first_name"));
emp.setLastName(rs.getString("last_name"));
emp.setEmail(rs.getString("email"));
emp.setGender(rs.getString("gender"));
emp.setMarriage(rs.getString("marriage"));
emp.setBirthday(rs.getDate("birthday"));
emp.setWorkat(rs.getString("workat"));
emp.setDepartment(rs.getString("department"));
return emp;
}
});
}
public long saveEmployee(Employee p)
{
/*
* SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
* System.out.println("DOB ::"+p.getBirthday()+"::"+format1.format(p.getBirthday
* ()));
*/
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
format1.format(p.getBirthday());
/*
* String sql
* ="insert into emsystem.employee(id,birthday,department,email,first_name,gender,last_name"
* + ",marriage,workat) values" + " ('"+p.getFirstName()+"','1','2021-08-06'" +
* ",'"+p.getDepartment()+"','"+p.getEmail()+"','"+p.getLastName()+"'," +
* "'"+p.getGender()+"','"+p.getLastName()+"','"+p.getMarriage()+"','"+p.
* getWorkat()+"');";
*/
String sql="insert into employee(id,firstName,lastName,email,gender,marriage,birthday,workat,department) values "
+
"('"+p.getId()+"',"+p.getFirstName()+","+p.getLastName()+","+p.getEmail()+","+p.getGender()
+","+p.getMarriage()+","+p.getBirthday()+","+p.getWorkat()+",'"+p.getDepartment()+"')";
System.out.println("SQL ::"+sql);
return jdbcTemplate.update(sql);
// return jdbcTemplate.update(sql);
}
//#Deprecated
public Employee getEmployeeById(Long id)
{
String sql="select * from employee where id=?";
//return jdbcTemplate.queryForObject("select * from employee where id=?",new BeanPropertyRowMapper<Employee>(Employee.class), new Object[]{id});
return jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<Employee>(Employee.class),new Object[]{id});
}
public long updateEmployee(Employee p)
{
String sql="update employee set firstName='"+p.getFirstName()+"', lastName="+p.getLastName()+",email="+p.getEmail()+",gender="+p.getGender()+",marriage="+p.getMarriage()+",birthday="+p.getBirthday()+",workat="+p.getWorkat()+",department='"+p.getDepartment()+"' where id="+p.getId()+"";
return jdbcTemplate.update(sql);
}
public long deleteEmployeeById(Long id)
{
String sql="delete from employee where id="+id+"";
return jdbcTemplate.update(sql);
}
}
Error
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sun Jul 11 11:01:50 IST 2021
There was an unexpected error (type=Bad Request, status=400).
Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long'; nested exception is java.lang.NumberFormatException: For input string: "{id}(id=1)"
org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long'; nested exception is java.lang.NumberFormatException: For input string: "{id}(id=1)"
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:133)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:170)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:228)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1723)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:831)
Caused by: java.lang.NumberFormatException: For input string: "{id}(id=1)"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Long.parseLong(Long.java:714)
at java.base/java.lang.Long.valueOf(Long.java:1166)
at org.springframework.util.NumberUtils.parseNumber(NumberUtils.java:214)
at org.springframework.beans.propertyeditors.CustomNumberEditor.setAsText(CustomNumberEditor.java:115)
at org.springframework.beans.TypeConverterDelegate.doConvertTextValue(TypeConverterDelegate.java:429)
at org.springframework.beans.TypeConverterDelegate.doConvertValue(TypeConverterDelegate.java:402)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:155)
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:73)
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:53)
at org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java:696)
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:125)
... 47 more
Controller
package net.javaguides.ems.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import net.javaguides.ems.entity.Employee;
#Controller // Controller Layer holds all Spring MVC Controllers
public class EmployeeController {
#Autowired
EmployeeDao employeeDao;
/*
* #GetMapping("/") //from this method will call findPaginated method -> this
* will return paginated Employees. public String viewHomePage(Model model) {
* return findPaginated(1, model); }
*/
//handler method to handle list employees and return mode and view
#GetMapping("/employees")
public String listEmployees(Model model)
{
model.addAttribute("employees", employeeDao.getAllEmployees());
return "employees";
}
#GetMapping("/employees/new")
public String createEmployeeForm(Model model)
{
//Create empty employee object to hold employee form data
Employee employee = new Employee();
model.addAttribute("employee", employee);
return "create_employee";
}
#PostMapping("/employees")
public String saveEmployee(#ModelAttribute("employee") Employee employee,
BindingResult bindingResult)
{
//Here, we r using ModelAttribute to directly bind form data to the employee object.
if (bindingResult.hasErrors())
{
return "create_employee";
}
else
{
employeeDao.saveEmployee(employee);
return "redirect:/employees";
}
}
#GetMapping("/employees/edit/{id}")
public String editEmployeeForm(#PathVariable Long id, Model model) //PathVariable Annotation is to get the id.
{
model.addAttribute("employee", employeeDao.getEmployeeById(id));
return "edit_employee";
}
#PostMapping("/employees/{id}")
public String updateEmployee(#PathVariable Long id,
#ModelAttribute("employee") Employee employee, BindingResult bindingResult, Model model)
{
// save updated employee object
if (bindingResult.hasErrors())
{
return "create_employee";
}
else
{
// get employee from database by id
Employee existingEmployee = employeeDao.getEmployeeById(id);
existingEmployee.setId(id);
existingEmployee.setFirstName(employee.getFirstName());
existingEmployee.setLastName(employee.getLastName());
existingEmployee.setEmail(employee.getEmail());
existingEmployee.setGender(employee.getGender());
existingEmployee.setMarriage(employee.getMarriage());
existingEmployee.setBirthday(employee.getBirthday());
existingEmployee.setWorkat(employee.getWorkat());
existingEmployee.setDepartment(employee.getDepartment());
employeeDao.updateEmployee(existingEmployee);
return "redirect:/employees";
}
}
// handler method to handle delete employee request
#GetMapping("/employees/{id}")
public String deleteEmployee(#PathVariable Long id)
{
employeeDao.deleteEmployeeById(id);
return "redirect:/employees";
}
}
DB configuration
package net.javaguides.ems;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
#Configuration
public class DBConfiguration {
#Autowired
private Environment env;
#Bean(name="dataSource")
public DataSource getDatasource() {
DriverManagerDataSource datasource = new DriverManagerDataSource();
//DataSource datasource = new DataSource();
datasource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));//this.dbDriver
datasource.setUrl(env.getProperty("spring.datasource.url"));//this.dbURL
datasource.setUsername(env.getProperty("spring.datasource.username"));//this.dbUserName
datasource.setPassword(env.getProperty("spring.datasource.password"));//this.dbPassword
return datasource;
}
#Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
/*
* #Bean("resourceBundle") public ResourceBundle resourceBundle() {
* ResourceBundle rb = ResourceBundle.getBundle("query"); return rb; }
*/
}
You haven’t included the URL that you are using to make the request, but, having seen your controller’s code, I think that’s the problem.
Judging by the error message, you are making a GET request to something like /employees/{id}(id=1). Your #GetMapping is /employees/{id} so everything after the second / becomes the value of id. Due to you use of #PathVariable, Spring MVC tries to convert "{id}(id=1)" to a Long for your id argument and it fails.
If my assumption about the URL to which you are making the request is correct, you can fix the problem by changing the URL that you’re using. Assuming that the employee’s ID is 1, it should be /employees/1.
The problem is that when you pass a parameter using the URL directly, for example
/employees/1
you are passing a String, whetever you like it or not. So the best solution would be
(this is one of the controllers, similar solutions applies to the others)
#GetMapping("/employees/{id}")
public String deleteEmployee(#PathVariable String id)
{
try {
Long longid = Long.valueOf(id);
catch (Exception e)
{
//Exception Handling here (maybe an error page, idk)
}
employeeDao.deleteEmployeeById(longid);
return "redirect:/employees";
}
Plus, I strongly recommend you to use custom repository, so you don't need to create standard queries like insertion, deletion, and standard selection everytime (look for CrudRepository or JpaRepository)
This question already has an answer here:
jdbc to MYSQL error: No suitable driver found for jdbc:mysql://localhost:3306/test?user='root'&password='' [duplicate]
(1 answer)
Closed 7 years ago.
I've put mysql driver in .../ROOT/WEB-INF/lib and Tomcat 8.0/lib but it has no effect. I'm using the following class to connect to DB:
package db;
import java.sql.*;
public class ConnectToDB implements AutoCloseable {
Connection con;
public ConnectToDB(String server, String database, String user,
String password) throws SQLException {
con = DriverManager.getConnection("jdbc:mysql://" + server + "/"
+ database, user, password);
}
#Override
public void close() throws SQLException {
con.close();
}
public Connection getConnection() {
return con;
}
}
The following classes are included in the Eclipse project:
1. src/nr3/model
package nr3.model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import db.ConnectToDB;
public class MusikkHandler {
private ConnectToDB db;
private Connection con;
private String tableName;
private PreparedStatement pstmtGetRows;
public MusikkHandler(String server, String database, String user,
String password) throws SQLException {
db = new ConnectToDB(server, database, user, password);
con = db.getConnection();
tableName = "album";
}
public void close() throws SQLException {
db.close();
}
public ArrayList<Album> getRows(String genre) throws SQLException {
ArrayList<Album> list = new ArrayList<Album>();
pstmtGetRows = con.prepareStatement("SELECT * FROM " + tableName
+ " WHERE SJANGER = ?");
pstmtGetRows.setString(1, genre);
ResultSet rs = pstmtGetRows.executeQuery();
while (rs.next()) {
list.add(new Album(rs.getString(1), rs.getString(2), rs.getInt(3),
rs.getInt(4), rs.getString(5)));
}
rs.close();
pstmtGetRows.close();
return list;
}
}
-
package nr3.model;
public class Album {
private String tittel;
private String artist;
private int spor;
private int utgitt;
private String sjanger;
public Album (String artist, String tittel, int spor, int utgitt, String sjanger){
setArtist(artist);
setTittel(tittel);
setUtgitt(utgitt);
setSpor(spor);
setSjanger(sjanger);
}
public Album(){
this(null, null, 0, 0, null);
}
public void setTittel(String tittel){
this.tittel = tittel;
}
public void setArtist(String artist){
this.artist = artist;
}
public void setSpor(int spor) {
this.spor = spor;
}
public void setUtgitt(int utgitt) {
this.utgitt = utgitt;
}
public void setSjanger(String sjanger) {
this.sjanger = sjanger;
}
public String getTittel() {
return tittel;
}
public String getArtist() {
return artist;
}
public int getSpor() {
return spor;
}
public int getUtgitt() {
return utgitt;
}
public String getSjanger() {
return sjanger;
}
public String toString(){
return getTittel() + " (" + getArtist() + ")" + " Utgitt: "
+ getUtgitt();
}
}
2. src/nr3/servlets
package nr3.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import nr3.model.Album;
import nr3.model.MusikkHandler;
public class MusikkValg extends HttpServlet {
private static final long serialVersionUID = 428937262021570370L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String genre = request.getParameter("sjanger");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html");
PrintWriter out = response.getWriter();
MusikkHandler mh;
out.println("<html>");
out.println("<head>");
out.println("<title>Musikk</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>MUSIKK-ANBEFALINGER</h1>");
out.println("<br/>");
out.println("<br/>");
out.println("<h3>Da bør du kanskje forsøke en av disse:</h3>");
out.println("<br/>");
out.println("<br/>");
try {
mh = new MusikkHandler(" ", " ", " ", " ");
for (Album a : mh.getRows(genre))
out.println("<p>" + a + "</p>");
} catch (SQLException e) {
e.printStackTrace(out);
}
out.println("</body>");
out.println("</html>");
}
}
Update: I've got the following error stacktrace in the browser:
java.sql.SQLException: No suitable driver found for
jdbc:mysql://localhost/pg3100 at
java.sql.DriverManager.getConnection(Unknown Source) at
java.sql.DriverManager.getConnection(Unknown Source) at
db.ConnectToDB.(ConnectToDB.java:10) at
nr3.model.MusikkHandler.(MusikkHandler.java:20) at
nr3.servlets.MusikkValg.doGet(MusikkValg.java:39) at
javax.servlet.http.HttpServlet.service(HttpServlet.java:618) at
javax.servlet.http.HttpServlet.service(HttpServlet.java:725) at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:534)
at
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1081)
at
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658)
at
org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:277)
at
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2381)
at
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2370)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
First, you must register your driver at the beginning so DriverManager can user it when getting a connection. It might vary on the implementation.
DriverManager.registerDriver (new com.mysql.jdbc.Driver());
or
Class.forName("com.mysql.jdbc.Driver");
Then you can perform a getConnection() because you'll have a driver registered to be used by DriverManager.
Second: /webapps/ROOT/WEB-INF/lib is a different context and its libraries won't be available for your app unless you are setting the context path of your app as shown in this question. If you wanna add it, try placing your JDBC driver on /webapps/<yourapp>/lib first. Tomcat lib should work as well (but it's not nice when you distribute your app, might conflict with other apps deployed there, using different versions of the driver, etc.)
Third: When asking here, try to reduce your verifiable example to something readable. There's a lot of code which is not relevant to your problem. Reducing makes it easier to read your question and provide help.
I have created a bean data source to connect to my database. My objective of creating this datasource is to switch datasource as per a parameter given. But when I run reports using the bean data source, it does not release the connection back into the pool. My connection pool size is 20, so when I run the 21st report, server hangs printing the following message on the JConsole
Name: pool-7-thread-9
State: WAITING on org.apache.commons.pool.impl.GenericObjectPool#1f8ed84
Total blocked: 0 Total waited: 4
Stack trace:
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:485)
org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:748)
org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:95)
com.loits.jasper.ds.SwitchDS.setReportParameterValues(SwitchDS.java:75)
com.jaspersoft.jasperserver.api.engine.jasperreports.service.impl.EngineServiceImpl.fillReport(EngineServiceImpl.java:1725)
com.jaspersoft.jasperserver.api.engine.jasperreports.service.impl.EngineServiceImpl$ReportFill.runWithDataSource(EngineServiceImpl.java:1086)
com.jaspersoft.jasperserver.api.engine.jasperreports.service.impl.EngineServiceImpl$ReportFill.runReport(EngineServiceImpl.java:1015)
com.jaspersoft.jasperserver.api.engine.jasperreports.service.impl.EngineServiceImpl$ReportRunnable.run(EngineServiceImpl.java:908)
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
java.lang.Thread.run(Unknown Source)
Here what I have done in my bean
package com.loits.jasper.ds;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.sql.SQLException;
import net.sf.jasperreports.engine.JRParameter;
import org.springframework.security.context.SecurityContextHolder;
import com.jaspersoft.jasperserver.api.metadata.jasperreports.domain.ReportDataSource;
import com.jaspersoft.jasperserver.api.metadata.jasperreports.service.ReportDataSourceService;
import com.jaspersoft.jasperserver.api.metadata.user.domain.Role;
import com.jaspersoft.jasperserver.api.metadata.user.domain.client.ProfileAttributeImpl;
import com.jaspersoft.jasperserver.api.metadata.user.domain.impl.client.MetadataUserDetails;
import com.jaspersoft.jasperserver.api.common.domain.ExecutionContext;
import com.jaspersoft.jasperserver.api.common.service.BeanForInterfaceImplementationFactory;
import com.jaspersoft.jasperserver.api.engine.jasperreports.service.impl.JdbcDataSourceService;
import com.jaspersoft.jasperserver.api.engine.jasperreports.service.impl.JdbcReportDataSourceServiceFactory;
import com.jaspersoft.jasperserver.war.common.JasperServerUtil;
import com.jaspersoft.jasperserver.api.metadata.common.service.RepositoryService;
public class SwitchDS implements ReportDataSourceService {
private JdbcDataSourceService connection;
private RepositoryService repositoryService;
private BeanForInterfaceImplementationFactory dataSourceServiceFactory;
// private DataSourceServiceFactory dataSourceServiceFactory;
public SwitchDS(RepositoryService repositoryService,
BeanForInterfaceImplementationFactory dsServiceFactory) {
super();
this.repositoryService = repositoryService;
this.dataSourceServiceFactory = dsServiceFactory;
System.out.println("repositoryService " + repositoryService);
System.out.println("dataSourceServiceFactory "
+ dataSourceServiceFactory);
}
#SuppressWarnings({ "unchecked", "rawtypes" })
public void setReportParameterValues(Map parametersValue) {
String ds_name = (String) parametersValue.get("P_SCM");
String ds_uri = "";
if(ds_name.equalsIgnoreCase("D_001_S")){
ds_uri = "/datasources/lolc_fusion";
}
else if(ds_name.equalsIgnoreCase("D_005_S")){
ds_uri = "/datasources/lofc_fusion";
}
else if(ds_name.equalsIgnoreCase("D_009_S")){
ds_uri = "/datasources/lomc_fusion";
}
else if(ds_name.equalsIgnoreCase("D_010_S")){
ds_uri = "/datasources/clc_fusion";
}
else if(ds_name.equalsIgnoreCase("D_025_S")){
ds_uri = "/datasources/lofac_fusion";
}
if(connection == null){
connection = getRepositoryDatasource(ds_uri);
}
try {
parametersValue.put(JRParameter.REPORT_CONNECTION, connection
.getDataSource().getConnection());
} catch (SQLException e) {
e.printStackTrace();
}
}
public JdbcDataSourceService getRepositoryDatasource(String repositoryURI) {
try {
ExecutionContext context = JasperServerUtil.getExecutionContext();
ReportDataSource datasource = (ReportDataSource) repositoryService
.getResource(context, repositoryURI);
System.out.println("datasource " + datasource.getName());
System.out.println("datasource class " + datasource.getClass());
JdbcReportDataSourceServiceFactory factory = (JdbcReportDataSourceServiceFactory) dataSourceServiceFactory
.getBean(datasource.getClass());
JdbcDataSourceService DSservice = (JdbcDataSourceService) factory
.createService(datasource);
return DSservice;
} catch (Exception ex) {
System.out.println(ex);
return null;
}
}
#Override
public void closeConnection() {
if (connection != null) {
connection.closeConnection();
System.out.println("Connection closed .. ");
}
}
public static void main(String[] args) {
}
}
Seems to me like you're closing the connection instead of returning it to the pool.
Simon
I manage to solve this problem getting hint from post stackoverflow post about GWT. The post tells that as JDBC shouldn'e be on client side, rather on server side.
I am trying to make a simple web application that adds a user to database using GWT RPC with Hibernate, MySql & eclipse IDE. I have already a simple version of hibernate program running & now I am trying to do same using GWT RPC.
Though probably there are certain different practices when using hibernate with RPC. Firstly I had to put jars/libs to war/web.inf/lib add before adding them to classpath, while I made a simple folder in src, put all jars/libraries to that & then added to classpath for simple hibernate app. It continues, compiler then raised error about unavailability of cfg.xml & mapping files which were in the hibernate files package(that contain pojo files). I moved them to src folder & error gone. But now error is about session creation. This time moving Util file to src did not work.
This is directory structure of my project:
src
hbm.xml
cfg.xml
hibDomain(hibernate package)
rppctest.client (GWT package)
rppctest.server (GWT package)
I am using MySQL on Windows 7.
Here are the error messages & my code.
errors
94 [btpool0-2] INFO org.hibernate.cfg.Environment - Hibernate 3.3.1.GA
126 [btpool0-2] INFO org.hibernate.cfg.Environment - hibernate.properties not found
173 [btpool0-2] INFO org.hibernate.cfg.Environment - Bytecode provider name : javassist
282 [btpool0-2] INFO org.hibernate.cfg.Environment - using JDK 1.4 java.sql.Timestamp handling
751 [btpool0-2] INFO org.hibernate.cfg.Configuration - configuring from resource: /hibernate.cfg.xml
751 [btpool0-2] INFO org.hibernate.cfg.Configuration - Configuration resource: /hibernate.cfg.xml
3657 [btpool0-2] INFO org.hibernate.cfg.Configuration - Reading mappings from resource : user.hbm.xml
4018 [btpool0-2] INFO org.hibernate.cfg.HbmBinder - Mapping class: com.hib.User -> users
Initial SessionFactory creation failed.org.hibernate.InvalidMappingException: Could not parse mapping document from resource user.hbm.xml
Starting Jetty on port 8888
[WARN] Exception while dispatching incoming RPC call
com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract java.lang.String rpctest.client.RpctestService.addUser(java.lang.String,java.lang.String) throws java.lang.IllegalArgumentException' threw an unexpected exception: java.lang.ExceptionInInitializerError
at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:385)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:588)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:208)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248)
at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:324)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:205)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
Caused by: java.lang.ExceptionInInitializerError
at hibDomain.HibernateUtil.buildSessionFactory(HibernateUtil.java:16)
at hibDomain.HibernateUtil.<clinit>(HibernateUtil.java:7)
at rpctest.server.RpctestServiceImpl.addUser(RpctestServiceImpl.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:569)
... 22 more
Caused by: org.hibernate.InvalidMappingException: Could not parse mapping document from resource user.hbm.xml
at org.hibernate.cfg.Configuration.addResource(Configuration.java:602)
at org.hibernate.cfg.Configuration.parseMappingElement(Configuration.java:1621)
at org.hibernate.cfg.Configuration.parseSessionFactory(Configuration.java:1589)
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1568)
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1542)
at org.hibernate.cfg.Configuration.configure(Configuration.java:1462)
at org.hibernate.cfg.Configuration.configure(Configuration.java:1448)
at hibDomain.HibernateUtil.buildSessionFactory(HibernateUtil.java:11)
... 29 more
Caused by: org.hibernate.MappingException: class com.hib.User not found while looking for property: firstName
at org.hibernate.util.ReflectHelper.reflectedPropertyClass(ReflectHelper.java:97)
at org.hibernate.mapping.SimpleValue.setTypeUsingReflection(SimpleValue.java:302)
at org.hibernate.cfg.HbmBinder.createProperty(HbmBinder.java:2193)
at org.hibernate.cfg.HbmBinder.createClassProperties(HbmBinder.java:2170)
at org.hibernate.cfg.HbmBinder.createClassProperties(HbmBinder.java:2060)
at org.hibernate.cfg.HbmBinder.bindRootPersistentClassCommonValues(HbmBinder.java:381)
at org.hibernate.cfg.HbmBinder.bindRootClass(HbmBinder.java:295)
at org.hibernate.cfg.HbmBinder.bindRoot(HbmBinder.java:166)
at org.hibernate.cfg.Configuration.add(Configuration.java:702)
at org.hibernate.cfg.Configuration.addInputStream(Configuration.java:537)
at org.hibernate.cfg.Configuration.addResource(Configuration.java:599)
... 36 more
Caused by: java.lang.ClassNotFoundException: com.hib.User
at java.lang.ClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:352)
at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:337)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at org.hibernate.util.ReflectHelper.classForName(ReflectHelper.java:123)
at org.hibernate.util.ReflectHelper.reflectedPropertyClass(ReflectHelper.java:93)
... 46 more
[ERROR] 500 - POST /rpctest/testService (127.0.0.1) 57 bytes
Request headers
Accept: */*
X-GWT-Permutation: HostedMode
X-GWT-Module-Base: http://127.0.0.1:8888/rpctest/
Content-Type: text/x-gwt-rpc; charset=utf-8
Referer: http://127.0.0.1:8888/Rpctest.html?gwt.codesvr=127.0.0.1:9997
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
Host: 127.0.0.1:8888
Content-Length: 168
Connection: Keep-Alive
Cache-Control: no-cache
Response headers
Content-Type: text/plain
entry point class
package rpctest.client;
import rpctest.shared.FieldVerifier;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class Rpctest implements EntryPoint {
final TextBox firstName = new TextBox();
final TextBox lastName = new TextBox();
final Button ans = new Button("Add User");
final Label label1 = new Label("First Name");
final Label label2 = new Label("Last Name");
//final Label errorLabel = new Label();
private VerticalPanel mainpanel = new VerticalPanel();
private HorizontalPanel addpanel1 = new HorizontalPanel();
private HorizontalPanel addpanel2 = new HorizontalPanel();
private final RpctestServiceAsync calNumbers = GWT
.create(RpctestService.class);
/**
* This is the entry point method.
*/
public void onModuleLoad() {
addpanel1.add(label1);
addpanel1.add(firstName);
addpanel2.add(label2);
addpanel2.add(lastName);
mainpanel.add(addpanel1);
mainpanel.add(addpanel2);
mainpanel.add(ans);
ans.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
String name1 = firstName.getValue();
String name2 = lastName.getValue();
calNumbers.addUser(name1,name2,
new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
Window.alert("check your inputs");
}
#Override
public void onSuccess(String result) {
// TODO Auto-generated method stub
Window.alert("User is ->"+result);
}
});}
});
// We can add style names to widgets
//sendButton.addStyleName("sendButton");
// Add the nameField and sendButton to the RootPanel
// Use RootPanel.get() to get the entire body element
/*RootPanel.get("nameFieldContainer").add(nameField);
*
RootPanel.get("sendButtonContainer").add(sendButton);
RootPanel.get("errorLabelContainer").add(errorLabel);*/
RootPanel.get().add(mainpanel);
}
}
interfaces
package rpctest.client;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
#RemoteServiceRelativePath("testService")
public interface RpctestService extends RemoteService {
String addUser(String firstName,String lastName) throws IllegalArgumentException;
}
package rpctest.client;
import com.google.gwt.user.client.rpc.AsyncCallback;
public interface RpctestServiceAsync {
void addUser(String firstName, String lastName,
AsyncCallback<String> callback);
}
Implementation
package rpctest.server;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import hibDomain.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;
import hibDomain.User;
import hibDomain.Task;
import rpctest.client.RpctestService;
public class RpctestServiceImpl extends RemoteServiceServlet implements RpctestService {
public String addUser(String name1, String name2)
throws IllegalArgumentException {
Transaction trns = null;
Session session = HibernateUtil.getSessionFactory().openSession();
try {
trns = session.beginTransaction();
User user = new User();
user.setFirstName(name1);
user.setLastName(name2);
session.save(user);
session.getTransaction().commit();
} catch (RuntimeException e) {
if(trns != null){
trns.rollback();
}
e.printStackTrace();
} finally{
session.flush();
session.close();
}
return name1;
}
}
Hibernate files
package hibDomain;
public class User {
private Integer id;
private String firstName;
private String lastName;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
mapping file
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.hib.User" table="users" >
<id name="id" type="int" column="id" >
<generator class="native"/>
</id>
<property name="firstName">
<column name="first_name" />
</property>
<property name="lastName">
<column name="last_name"/>
</property>
</class>
</hibernate-mapping>
cfg file
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/userdata</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<!-- Mapping files -->
<mapping resource="user.hbm.xml"/>
<mapping resource="task.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Util
package hibDomain;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new Configuration().configure().buildSessionFactory();
}
catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Your hibernate class file (User) is in "hibDomain" package. where as the mapping you are making is for "com.hib.User". change this to hibDomain.User and it might work.
I don't like Jackson.
I want to use ajax but with Google Gson.
So I'm trying to figure out how to implement my own HttpMessageConverter to use it with #ResponseBody annotation.
Can someone take a time to show me the way I should go? What configurations should I turn on?
Also I'm wondering if I can do this and still use <mvc:annotation-driven />?
Thanks in advance.
I've already asked it in Spring Community Foruns about 3 days ago with no answer so I'm asking here to see if I get a better chance.
Spring Community Forums link to my question
I've also made an exhaustive search on the web and found something interesting on this subject but it seems they're thinking to put it in Spring 3.1 and I'm still using spring 3.0.5:
Jira's Spring Improvement ask
Well... now I'm trying to debug Spring code to find out myself how to do this, but I'm having some problems like I've said here:
Spring Framework Build Error
If there is another way to do this and I'm missing it, please let me know.
Well... it was so hard to find the answer and I had to follow so many clues to incomplete information that I think it will be good to post the complete answer here. So it will be easier for the next one searching for this.
First I had to implement the custom HttpMessageConverter:
package net.iogui.web.spring.converter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
public class GsonHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
private Gson gson = new Gson();
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
public GsonHttpMessageConverter(){
super(new MediaType("application", "json", DEFAULT_CHARSET));
}
#Override
protected Object readInternal(Class<? extends Object> clazz,
HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
try{
return gson.fromJson(convertStreamToString(inputMessage.getBody()), clazz);
}catch(JsonSyntaxException e){
throw new HttpMessageNotReadableException("Could not read JSON: " + e.getMessage(), e);
}
}
#Override
protected boolean supports(Class<?> clazz) {
return true;
}
#Override
protected void writeInternal(Object t,
HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
//TODO: adapt this to be able to receive a list of json objects too
String json = gson.toJson(t);
outputMessage.getBody().write(json.getBytes());
}
//TODO: move this to a more appropriated utils class
public String convertStreamToString(InputStream is) throws IOException {
/*
* To convert the InputStream to String we use the Reader.read(char[]
* buffer) method. We iterate until the Reader return -1 which means
* there's no more data to read. We use the StringWriter class to
* produce the string.
*/
if (is != null) {
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} finally {
is.close();
}
return writer.toString();
} else {
return "";
}
}
}
Then I had to strip off the annnotaion-driven tag and configure all by my own hands on the spring-mvc configuration 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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
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">
<!-- Configures the #Controller programming model -->
<!-- To use just with a JSR-303 provider in the classpath
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
-->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="webBindingInitializer">
<bean class="net.iogui.web.spring.util.CommonWebBindingInitializer" />
</property>
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter" />
<bean class="net.iogui.web.spring.converter.GsonHttpMessageConverter" />
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter" />
<bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter" />
<!-- bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter" /-->
</list>
</property>
</bean>
<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<context:component-scan base-package="net.iogui.teste.web.controller"/>
<!-- Forwards requests to the "/" resource to the "login" view -->
<mvc:view-controller path="/" view-name="home"/>
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources/ directory -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/view/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
See that, to make the Formater and Validator to work, we have to build a custom webBindingInitializer too:
package net.iogui.web.spring.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.ConversionService;
import org.springframework.validation.Validator;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.WebBindingInitializer;
import org.springframework.web.context.request.WebRequest;
public class CommonWebBindingInitializer implements WebBindingInitializer {
#Autowired(required=false)
private Validator validator;
#Autowired
private ConversionService conversionService;
#Override
public void initBinder(WebDataBinder binder, WebRequest request) {
binder.setValidator(validator);
binder.setConversionService(conversionService);
}
}
An Interesting thing to see is that In order to make the configuration work without the annotaion-driven tag, we have to manually configure a AnnotationMethodHandlerAdapter and a DefaultAnnotationHandlerMapping. And in order to make the AnnotationMethodHandlerAdapter capable of handling formatting and validation, we had to configure a validator, a conversionService and to build a custom webBindingInitializer.
I hope all this helps someone else besides me.
On my desperate search, this #Bozho post was extremely util. I am also grateful to #GaryF couse his answer took me to the #Bozho post.
To you that are trying to do this in Spring 3.1, see #Robby Pond answer.. A lot easier, isn't it?
You need to create a GsonMessageConverter that extends AbstractHttpMessageConverter and use the mvc-message-converters tag to register your message converter. That tag will let your converter take precedence over the Jackson one.
If you want to add a message converter without messing with xml here is a simple example
#Autowired
private RequestMappingHandlerAdapter adapter;
#PostConstruct
public void initStuff() {
List<HttpMessageConverter<?>> messageConverters = adapter.getMessageConverters();
BufferedImageHttpMessageConverter imageConverter = new BufferedImageHttpMessageConverter();;
messageConverters.add(0,imageConverter);
}
I had situation where usage of Jackson would require me to alter other group's (in the same company) code. Didn't like that. So I chose to use Gson and register TypeAdapters as needed.
Hooked up a converter and wrote a few integration tests using spring-test (used to be spring-mvc-test). No matter what variation I tried (using mvc:annotation-driven OR manual definition of the bean). None of them worked. Any combination of these always used the Jackson Converter which kept on failing.
Answer> Turns out that MockMvcBuilders' standaloneSetup method "hard" coded the message converters to default versions and ignored all my changes above. Here is what worked:
#Autowired
private RequestMappingHandlerAdapter adapter;
public void someOperation() {
StandaloneMockMvcBuilder smmb = MockMvcBuilders.standaloneSetup(controllerToTest);
List<HttpMessageConverter<?>> converters = adapter.getMessageConverters();
HttpMessageConverter<?> ary[] = new HttpMessageConverter[converters.size()];
smmb.setMessageConverters(conveters.toArray(ary));
mockMvc = smmb.build();
.
.
}
Hope this helps someone, in the end I used annotation-driven and re-purposing android's converter
Notice that GsonHttpMessageConverter was added recently to Spring (4.1)
Robby Pond is basically correct, but note that his suggestion to use the mvc:message-converters tag requires that you use 3.1. Since 3.1 is currently only a milestone release (M1), I'd suggest registering your converter this way after creating it:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<util:list id="beanList">
<ref bean="someMessageConverter"/>
<ref bean="someOtherMessageConverter"/>
</util:list>
</property>
</bean>
Or as mentioned in Jira's Spring Improvement ask, write a BeanPostProcessor that adds your HttpMessageConvertor to the AnnotationMethodHandlerAdapter
You can do this by writing the WebConfig file as a Java File. Extend your config file with WebMvcConfigurerAdapter and override extendMessageConverters method to add your intented Message Convertor. This method will retain the default converters added by Spring and will add your convertor at the end. Apparently you have full control with the list and you can add where ever you want in the list.
#Configuration
#EnableWebMvc
#ComponentScan(basePackageClasses={WebConfig.class})
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new GsonHttpMessageConverter());
}
}
package net.iogui.web.spring.converter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
public class GsonHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
private Gson gson = new Gson();
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
public GsonHttpMessageConverter(){
super(new MediaType("application", "json", DEFAULT_CHARSET));
}
#Override
protected Object readInternal(Class<? extends Object> clazz,
HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
try{
return gson.fromJson(convertStreamToString(inputMessage.getBody()), clazz);
}catch(JsonSyntaxException e){
throw new HttpMessageNotReadableException("Could not read JSON: " + e.getMessage(), e);
}
}
#Override
protected boolean supports(Class<?> clazz) {
return true;
}
#Override
protected void writeInternal(Object t,
HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
//TODO: adapt this to be able to receive a list of json objects too
String json = gson.toJson(t);
outputMessage.getBody().write(json.getBytes());
}
//TODO: move this to a more appropriated utils class
public String convertStreamToString(InputStream is) throws IOException {
/*
* To convert the InputStream to String we use the Reader.read(char[]
* buffer) method. We iterate until the Reader return -1 which means
* there's no more data to read. We use the StringWriter class to
* produce the string.
*/
if (is != null) {
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} finally {
is.close();
}
return writer.toString();
} else {
return "";
}
}