Spring MVC 3.0 Getting Values Out From Sql Query - java

I am newbie in using Spring MVC 3.0. I am writing a custom authentication class and I would like to know how I can extract the values from a SQL query into variables? Here is an example of what I am trying to achieve, and some code, which I am asking about, is omitted;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.log4j.Logger;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import com.crimetrack.DAO.LoginDAO;
import com.crimetrack.business.Login;
public class JdbcLoginDAO extends JdbcDaoSupport implements LoginDAO {
private final Logger logger = Logger.getLogger(getClass());
String dbUserName;
String dbPassword;
public boolean AuthenticateUser(Login login) {
logger.debug("Authenticating User");
String sql = "SELECT userName, password FROM tblofficers WHERE userName = :userName AND password = :password ";
//code for parameters : userName and password using login.getPassword() and login.getUsername()
//and code to get vaules out from query for comparison
if (dbUserName == login.getUserName()) {
if (dbPassword == login.getPassword()){
return true;
}
}
return false;
}
public static class LoginMapper implements ParameterizedRowMapper<Login>{
public Login mapRow(ResultSet rs, int rowNum) throws SQLException {
Login dbLogin = new Login();
dbLogin.setUserName(rs.getString("userName"));
dbLogin.setPassword(rs.getString("password"));
return dbLogin;
}
}
}

Return the query as another instance of your "Login" class using JDBCTemplate and BeanPropertyRowMapper and then compare the objects.
You'll have to look into JDBCTemplate to define the database connection but eventually this would look like:
UserLogin authenticLogin = (UserLogin) db_connection.queryForObject(sql, new BeanPropertyRowMapper(UserLogin.class));
if (userLogin.getPassword() == authenticLogin.getPassword()) {
return true
}
Basically, BeanPropertRowMapper will create a new instance of a class settting any properties with the same names as columns returned from the query.

Related

I'm getting error in particular line....what should I change?

This is the line where I'm getting the error
List<Map<String, Object>> users = jdbcTemplate.queryForList("select * from user where email=? and pass=?",new Object[] { email, pass }, new MyRowMapper());
This is the whole code:
package com.example.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import com.example.model.User;
#Repository
public class UserDao {
#Autowired
private JdbcTemplate jdbcTemplate;
public int insert(User user) {
return jdbcTemplate.update("insert into user values(?,?,?,?,?)",
new Object[] { user.getName(), user.getEmail(), user.getPass(),user.getProfileimage(),user.getExpensetable() });
}
public int updateProfile(User user) {
return jdbcTemplate.update("update user set name=?,pass=?,profile=?,expensetable=? where email=?",
new Object[] { user.getName(), user.getPass(), user.getProfileimage(),user.getExpensetable(), user.getEmail() });
}
public User login(String email, String pass) {
User user = null;
List<Map<String, Object>> users = jdbcTemplate.queryForList("select * from user where email=? and pass=?",new Object[] { email, pass }, new MyRowMapper());
if (users.size() > 0) {
user = (User) users.get(0);
}
return user;
}
private class MyRowMapper implements RowMapper<User> {
#Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User();
user.setName(rs.getString(1));
user.setEmail(rs.getString(2));
user.setPass(rs.getString(3));
user.setProfileimage(rs.getString(4));
user.setExpensetable(rs.getString(5));
return user;
}
}
}
This is the error:
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/ExpenseSpringProject] threw exception [Request processing failed; nested exception is org.springframework.dao.TransientDataAccessResourceException: PreparedStatementCallback; SQL [select * from user where email=? and pass=?]; Invalid argument value: java.io.NotSerializableException; nested exception is java.sql.SQLException: Invalid argument value: java.io.NotSerializableException] with root cause
java.io.NotSerializableException: com.example.dao.UserDao$MyRowMapper
You are calling the wrong JdbcTemplate method.
The method you are calling takes a query and a varargs array of the bind parameter values. The way you are calling it, you are passing the following as bind parameter values:
an array containing your email and password.
a row-mapper.
The row-mapper is not being used to map rows, instead you are attempting to pass it to the database as if it is a value itself.
I think you want to use the overload of JdbcTemplate.query that takes a query, a row-mapper and the bind parameter values in that order.
Try replacing the line
List<Map<String, Object>> users = jdbcTemplate.queryForList("select * from user where email=? and pass=?",new Object[] { email, pass }, new MyRowMapper());
with
List<User> users = jdbcTemplate.query("select * from user where email=? and pass=?", new MyRowMapper(), email, pass);
Once you've done that, the cast to User in the line user = (User) users.get(0); should become unnecessary and you can remove it.

Questions regarding JSP & servlet & MongoDB Mlab

I am new to MongoDB Mlab, which means not familiar with how to use it and how to connect it with a DAO file. And I encounter a technical issue on SERVLET. Firstly, I try to extract data from MongoDB mlab to get an email & password of a user for my login page. And I also capture the email & password entered by a user on login JSP page by using "request.getParameter("")" method. These two points work fine because I already tested them. More info about my issue is that when I try to extract email and password from MongoDB mlab, I store these two parameters into a user object, and store the user object into an ArrayList. Then return this Arraylist to the login Servlet. Using for-each loop to traversal this list. I put the codes below.
When I try to enter an email and password on the login page, this is the result I encountered
how can I solve it
FDao.java
package Dao;
import static com.sun.corba.se.spi.presentation.rmi.StubAdapter.request;
import java.net.UnknownHostException;
import java.sql.*;
import java.util.*;
import javax.servlet.RequestDispatcher;
import model.Book;
import model.Staff;
import model.User;
import org.bson.Document;
public class FDao {
public List<User> checkLogin() throws UnknownHostException {
Iterator it = DB.getDB().getCollection("users").find().iterator();
List<User> aUser = new ArrayList();
while(it.hasNext()){
Document o = (Document) it.next();
aUser.add(new User(o.getString("email"), o.getString("password")));
}
return aUser;
}
}
LoginServlet.java(I capture string email and string password from login JSP page)
#WebServlet("/Login")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public LoginServlet() {
super();
}
FDao userDao = new FDao();
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
String email = request.getParameter("email");
String password = request.getParameter("pass");
List<User> users = new ArrayList();
users = userDao.checkLogin();
for (User user : users) {
if (email.equals(user.getEmail()) && password.equals(user.getPassword()) ) {
//HttpSession session = request.getSession();
//session.setAttribute("user", user);
request.getRequestDispatcher("/home.jsp").include(request, response); //the problem looks like appeared in this line of code
//out.println("Hello World");
} else {
//String message = "Your account does not exist in out database!";
//request.setAttribute("message", message); //message is object
request.getRequestDispatcher("/Login.jsp").include(request, response);//the problem looks like appeared in this line of code
//out.println("Nothing");
}
break;
}
}
}

Update query execute successful but table in Java database on netbeans is not updating even with the update statement

My java database is not updating but the query executed successfully. I'm trying to call my update method from a class named "ProductClass" and put the method into my jframe source code "UpdateProductForm". But I'm not sure if this issue is due to an error in creating my update method or an error in calling my update method. Note that there is no Error message given by the compiler.I need help badly. Thanks in Advance.
My ProductClass
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ProductClass extends MaterialClass implements Addable, Updatable, Deletable {
public int PRODUCT_ID;
public String PRODUCT_NAME;
public String PRODUCT_BRAND;
public String PRODUCT_MODEL;
public String PRODUCT_TYPE;
public int PRODUCT_PRICE;
public int MATERIAL_ID;
public ProductClass(int PRODUCT_ID, String PRODUCT_NAME, String PRODUCT_BRAND, String PRODUCT_MODEL, String PRODUCT_TYPE, int PRODUCT_PRICE, int MATERIAL_ID)
{
}
public ProductClass(int PRODUCT_ID)
{
}
#Override
public boolean Update()
{
try
{
Connection conn= DriverManager.getConnection("jdbc:derby://localhost:1527/KDatabase","koushal","456");
String query= "UPDATE PRODUCT SET PRODUCT_NAME= '"+PRODUCT_NAME+"' ,PRODUCT_BRAND= '"+PRODUCT_BRAND+"' ,PRODUCT_MODEL= '"+PRODUCT_MODEL+"' ,PRODUCT_TYPE='"+PRODUCT_TYPE+"',PRODUCT_PRICE= "+PRODUCT_PRICE+" ,MATERIAL_ID= "+MATERIAL_ID+" where PRODUCT_ID= "+PRODUCT_ID+" ";
PreparedStatement statement =conn.prepareStatement(query);
statement.executeUpdate();
return true;
}
catch (SQLException ex)
{
Logger.getLogger(SystemAdministrator.class.getName()).log(Level.SEVERE, null, ex);
}
return false;
}
}
My UpdateProductForm where I'm trying to call the method update. Update Successful here but my database not updated
private void UpdateButtonActionPerformed(java.awt.event.ActionEvent evt) {
int value1=Integer.parseInt(Ptd_IDtxtField.getText());
String value2=Ptd_NametxtField.getText();
String value3=PtdBrand_txtField.getText();
String value4=PtdModel_txtField.getText();
String value5=PtdType_txtField.getText();
int value6=Integer.parseInt(PtdPrice_txtField.getText());
int value7=Integer.parseInt(MaterialID_txtField.getText());
ProductClass object = new ProductClass(value1,value2,value3,value4,value5,value6,value7);
if(object.Update()==true)
{
JOptionPane.showMessageDialog(null,"Update Successful");
}
}
this is my Updatable Public Interface
public interface Updatable {
/**
*
* #return
*/
public boolean Update();
}
Your update missing commit statement at the end
conn.commit();
And also close your resources, preferqbly using try with resources since java 7, see more in docs

How to take input for a web service in java

I am trying to write a simple web service that must take a number as input and return details corresponding to it.
Here is my code that I have written till now.
package webserviceapp;
import java.sql.Statement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import javax.jws.WebService;
import javax.jws.WebMethod;
#WebService
public class WebServiceApp {
/**
* #param args the command line arguments
*/
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://10.100.66.28:3306/dbname";
// Database credentials
static final String USER = "user";
static final String PASS = "pass";
static Map<Integer, String> map = new HashMap<Integer, String>();
public static void main(String[] args) {
// TODO code application logic here
Connection conn;
Statement stmt;
try{
Class.forName(JDBC_DRIVER);
conn = DriverManager.getConnection(DB_URL, USER, PASS);
stmt = (Statement) conn.createStatement();
String sql = "Select * from table";
ResultSet rs;
rs = stmt.executeQuery(sql);
while(rs.next()){
//do something
}
}catch(ClassNotFoundException | SQLException e){
System.out.println(e);
}
}
#WebMethod(action = "returnDetails")
public static String[] returnDetails(int k) throws notFoundException{
//do the work
//returns String[]
}
private static class notFoundException extends Exception {
public notFoundException(String s) {
System.out.println(s);
System.err.println(s);
}
}
}
I do not know how to take input for the above web service. I have a html page that has a text box and submit button for which I get values through a php code. I want to tunnel this number as input to my web service. Can anyone tell me how can I proceed.
Also, I want the output String[] to be returned to php code so it can be displayed on the html page.
Thanks in advance.
you can pass it in the URL and from the url you can get the values in java
Working off the assumption that you are looking to invoke a RESTful service, there are multiple ways of obtaining input parameters. You can refer to the below article for the ways to achieve this -
http://www.java4s.com/web-services/how-restful-web-services-extract-input-parameters
Code examples for each are available at http://www.java4s.com/web-services/
Another good article you can refer to is - https://vrsbrazil.wordpress.com/2013/08/07/passing-parameters-to-a-restful-web-service/

Why does Hibernate transaction not update my database?

I'm having an issue with my login class. If a user unsuccessfully attempts to login with a username then that user account should be disabled. At runtime there are no errors but nothing changes in my database. Am I doing something wrong with updating my database through Hibernate, I thought I could just use my UserBean.class to access properties, change them and then commit the Hibernate transaction?
Here is my LoginDAO.class:
package com.sga.app.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.context.internal.ManagedSessionContext;
import org.hibernate.criterion.Restrictions;
import org.owasp.encoder.Encode;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import com.sga.app.beans.UserBean;
import com.sga.app.hibernate.HibernateUtil;
import com.sga.app.security.LoginFailureEventListener;
import com.sga.app.security.XssRequestWrapper;
#Component("loginDAO")
#Transactional
#Configuration
public class LoginDAO implements
ApplicationListener<AuthenticationFailureBadCredentialsEvent> {
private int loginAttemptsThreshold;
private int failedLoginAttempts;
private static Logger logger = Logger
.getLogger(LoginFailureEventListener.class);
private static Session session;
private Criteria criteria;
private String username;
private boolean enabled;
private String forename;
private String authority;
private XssRequestWrapper xssReqWrapper;
private PreparedStatement prepStmtUsers;
private PreparedStatement prepStmtAuthorities;
private String URL = "jdbc:oracle:thin:system/sgaWebApp#localhost:1521/XE";
private String updateUsersStatement = "insert into users (username, password)
values (:username, :password)";
private String updateAuthoritiesStatement = "insert into authorities (username,
authority) values (:username, :authority)";
#Bean
public LoginDAO loginDAO() {
return new LoginDAO();
}
public void setLoginAttemptsThreshold(int threshold) {
this.loginAttemptsThreshold = threshold;
}
#Transactional
public void loginUser(UserBean user, BindingResult result) {
try {
Connection conn = DriverManager.getConnection(URL);
// clean out any possible XSS injection
String cleanUsernameValueInput = cleanOutXSSVulnerabilities("j_username");
String cleanPasswordValueInput = cleanOutXSSVulnerabilities("j_password");
// OWASP encoding
String safeUsername = Encode.forHtml(cleanUsernameValueInput);
prepStmtUsers.setString(1, safeUsername);
String safePassword = Encode.forHtml(cleanPasswordValueInput);
prepStmtUsers.setString(2, safePassword);
prepStmtAuthorities.setString(1, safeUsername);
String safeUserAuthority = Encode.forHtml(user.getAuthority());
prepStmtAuthorities.setString(2, safeUserAuthority);
// execute login process
prepStmtUsers = conn.prepareStatement(updateUsersStatement);
prepStmtAuthorities = conn
.prepareStatement(updateAuthoritiesStatement);
prepStmtUsers.executeUpdate();
prepStmtAuthorities.executeUpdate();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
} catch (AccessDeniedException accessDenied) {
accessDenied.printStackTrace();
}
}
private String cleanOutXSSVulnerabilities(String input) {
return xssReqWrapper.cleanXSS(input);
}
#Override
public void onApplicationEvent(
AuthenticationFailureBadCredentialsEvent event) {
if (event.getException().getClass()
.equals(UsernameNotFoundException.class)) {
return;
}
// print registration attempts to log file for security investigation if
// required
logger.info("Registration attempt failed: " + event.getException());
logger.info("Registration attempt number: " + event.getTimestamp());
String userId = event.getAuthentication().getName();
logger.info("FAILED LOGIN ATTEMPT NUMBER "
+ recordLoginAttempts(userId));
recordLoginAttempts(userId);
if (recordLoginAttempts(userId) >= loginAttemptsThreshold) {
lockoutUser(userId);
}
}
private int recordLoginAttempts(String userId) {
failedLoginAttempts++;
return failedLoginAttempts;
}
#SuppressWarnings("unchecked")
private ArrayList<UserBean> getUserAccountDetails(String input) {
ArrayList<UserBean> returnValues = new ArrayList<UserBean>();
session = HibernateUtil.createSessionFactory().openSession();
session.setFlushMode(FlushMode.MANUAL);
ManagedSessionContext.bind(session);
session.beginTransaction();
criteria = session.createCriteria(UserBean.class);
List<UserBean> retrievedUser = criteria.add(
Restrictions.like("username", input)).list();
for (UserBean userDetails : retrievedUser) {
logger.debug("USERNAME INSIDE THE GET USER ACCOUNT DETAILS METHOD: "
+ userDetails.getUsername());
logger.debug("AUTHORITY INSIDE THE GET USER ACCOUNT DETAILS METHOD: "
+ userDetails.getAuthority());
returnValues.add(userDetails);
}
session.flush();
session.getTransaction().commit();
session.close();
return returnValues;
}
private void lockoutUser(String userId) {
ArrayList<UserBean> userAccountValues = getUserAccountDetails(userId);
session = HibernateUtil.createSessionFactory().openSession();
session.setFlushMode(FlushMode.MANUAL);
ManagedSessionContext.bind(session);
session.beginTransaction();
for (UserBean user : userAccountValues) {
username = user.getUsername();
forename = user.getForename();
enabled = user.getEnabled();
authority = user.getAuthority();
logger.debug("USERNAME: " + username);
logger.debug("FORENAME: " + forename);
logger.debug("ENABLED BEFORE CHANGE: " + enabled);
user.setEnabled(false);
logger.debug("AUTHORITY BEFORE CHANGE: " + authority);
user.setAuthority("BLOCKED");
}
session.flush();
session.getTransaction().commit();
logger.debug("ENABLED AFTER CHANGE: " + enabled);
logger.debug("AUTHORITY AFTER CHANGE: " + authority);
session.close();
ManagedSessionContext.unbind(HibernateUtil.createSessionFactory());
}
}
I don't think you should be invoking openSession in that manner. I would highly suggest you rewrite the method to not do any "session" related work at all. Let Spring handle it, especially since you are already using #Transactional.
Either way, in the lockoutUser() method, the users you find, aren't bound to the session that gets created after it.
ArrayList<UserBean> userAccountValues = getUserAccountDetails(userId);
session = HibernateUtil.createSessionFactory().openSession();
So, later in the method when you update the user instances of that ArrrayList, the session doesn't realize that the user instances are to be persisted because the session was never tracking them.
Try to have only one session per thread. Each method can have its own transaction, but we rarely come across situations where we need more than one session in a thread. This doesn't seem to be that kind of a situation.
session.flush();
session.getTransaction().commit();
session.close();
Try to delete session.flush(); or put it after session.getTransaction().commit(); may work.
It doesn't appear that you call session.save(Object) or session.update(Object).

Categories