마푸
11
2020-05-17 13:35:01
5
204

Spring 입문 Spring, mybatis 관련 질문드립니다!


제가 처음 Spring 시작하고 이제 막 로그인을 구현해보려고하는데 Mybatis를 연동했습니다!

이 전에는 H2DB 써서 간단하게 했는데 오류가 나서 DB문젠가 싶어 Mybatis를 배우고 다시 해봤으나 똑같은 오류가 나서 질문드립니다.

sqlSession.selectList나 SelectOne 이런걸로 값을 return 하는데 nullPointerException이 발생하더군요! 아무리 검색하고 찾아봐도 안나오네요 도움 좀 구하겠습니다 ㅠㅠ


디렉토리 구조입니다.




오류 사진입니다.



DispatcherServlet 파일입니다.

public class DispatcherServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
                            throws ServletException, IOException {
        process(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
                            throws ServletException, IOException {
        request.setCharacterEncoding("EUC-KR");
        process(request, response);
    }

    private void process(HttpServletRequest request, HttpServletResponse response)
                            throws IOException {
        String uri = request.getRequestURI();
        String path = uri.substring(uri.lastIndexOf("/"));
        System.out.println(path);

        if(path.equals("/login.do")) {
            LoginMethod(request, response);
        } else {
            System.out.println("404 Error");
        }
    }

    private void LoginMethod(HttpServletRequest request, HttpServletResponse response)
                            throws IOException {
        System.out.println("Logining ...");

        String id = request.getParameter("id");
        String password = request.getParameter("password");

        UserVO vo = new UserVO();
        vo.setId(id);
        vo.setPassword(password);

        UserDAO userDAO = new UserDAO();
        UserVO user = userDAO.getUser(vo);

        if(user != null) {
            response.sendRedirect("index.jsp");
        } else {
            response.sendRedirect("login.jsp");
        }
    }
}


UserAbstractDAO 파일입니다.

public class UserAbstractDAO implements UserInterfaceDAO{
    @Autowired
    private SqlSessionTemplate sqlSession;

    @Override
    public UserVO selectOneParam(String queryId, Object params) {
        return sqlSession.selectOne(queryId, params);
    }

    @Override
    public List<UserVO> selectAll(String queryId) {
        System.out.println(1);
        return sqlSession.selectList(queryId);
    }
}

제가 사용하는건 selectAll이라는 메소드고 이걸 가지고 User 테이블에 있는 로그인 정보들을 몽땅 불러와서 띄워보기라도 하려고 했습니다.


UserDAO 파일 입니다.

@Repository
public class UserDAO extends UserAbstractDAO{
    public UserVO getUser(UserVO vo) {
        System.out.println("===> JDBC로 getUser() 기능 처리");
        //Object[] args = {vo.getId(), vo.getPassword()};

        //System.out.println(1);
        //UserVO test = (UserVO) selectOneParam("com.study.biz.user.impl.UserInterfaceDAO.selectOneParam", args);

        //System.out.println(test.toString());

        //return (UserVO) selectOneParam("com.study.biz.user.impl.UserInterfaceDAO.selectOneParam", args);
        List<UserVO> list = selectAll("com.study.biz.user.impl.UserInterfaceDAO.selectAll");
        for(UserVO item : list) {
            System.out.println(item.toString());
        }

        return null;
    }
}


UserServiceImpl 파일입니다.

@Service("userService")
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDAO userDAO;

    public void setUserDAO(UserDAO userDAO) { this.userDAO = userDAO; }

    public UserVO getUser(UserVO vo) { return userDAO.getUser(vo); }
}


web.xml 입니다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext.xml
            classpath*:config/context-*.xml
        </param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>action</servlet-name>
        <servlet-class>com.study.view.controller.DispatcherServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>action</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    <absolute-ordering/>
</web-app>


mapper 폴더에 넣어논 USER_ALLSELECT_SQL.xml입니다.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.study.biz.user.impl.UserInterfaceDAO">
    <select id="selectAll" parameterType="string"
            resultType="com.study.biz.user.UserVO">

        select id, password, name, role
        from users

    </select>
</mapper>


resource/config/context-mapper.xml 파일입니다.

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/conmtext/spring-context.xsd">

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations" value="classpath:/mapper/**/*_SQL.xml"/>
    </bean>

    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>

</beans>


resources/config/context-datasource.xml 입니다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                          http://www.springframework.org/schema/jdbc
                          http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd">
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8&amp;serverTimezone=UTC"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
</beans>





맨 위의 오류가 왜나는지 정말 모르겠습니다. 제가 System.out.println의 위치로도 해보고 스택 백트레이스? 그것도 읽어본걸로는 위의 UserAbstractDAO에 있는 SelectAll 메소드에서 resturn sqlSession.selectList(queryId); 이 분에서 nullPointerException이 발생하고 있습니다.


마찬가지로 있는 selectOneParam 메소드로 해도 똑같은 오류가 발생했구요.


제가 추측하건데 UserDAO에서 selectAll을 호출할때 사용하는 queryId 매개변수. mapper의 namespace와 queryId 연결하는 문자열이 인식이 안되는 걸 수도 있다고 생각하고, 그게 아니라면 설정파일이 잘못되서 연결이 안되어있는 걸 수도 있다고 생각했습니다.


query문은 걱정하지 않으셔도 이미 테스트해서 정상 작동하는거 mysql로 확인했습니다.


또한, 홈페이지에서 login.do 요청 보내면 DispatcherServlet에 login.do로 넘어가는 것도 확인했습니다. 이상한 요청하면 DispatcherServlet의 else문인 404 Error가 콘솔에 출력되고 있고요!!


정말 도와주세요 ㅠㅠㅠ 몇 일 째 해결이 안되용

아 추가적으로 DispatcherServlet 안쓰고 jsp에서 Servlet역할하는 페이지 하나 만들어서 JSP Script만 처리하도록 했을 때도 안됬었습니다!

0
0
  • 답변 5

  • John Suhr
    2k
    2020-05-17 13:50:40

    new 생성자로 접근하는 경우 SqlSession은 주입받을 수 없으므로 null이 됩니다.

    UserDAO userDAO = new UserDAO();
    UserVO user = userDAO.getUser(vo);


    1
  • 마푸
    11
    2020-05-17 13:52:22

    그러면 혹시 어떻게 주입을 해야 하는지 알 수 있을까요 ..? 

    힌트라도 주시면 공부해보겠습니다!

    0
  • John Suhr
    2k
    2020-05-17 13:54:44
    그리고 DispatcherServlet은 단순히 HttpServlet의 구현체일 뿐만 아니라 내부에 자신만의 ApplicationContext를 가지고 있으며, 루트 ApplicationContext가 있으면 둘 다 참조하여 빈을 찾습니다. 직접 만드신 DispatcherServlet은 해당 기능이 없으므로 DI가 제대로 동작하지 않습니다..
    1
  • John Suhr
    2k
    2020-05-17 13:56:35

    직접 만드신 DispatcherServlet을 사용하지 마시고, Controller - Service - Repository 패턴의 레이어를 구성해서 사용하고자 하는 Bean은 주입받아서 사용하세요

    1
  • 마푸
    11
    2020-05-17 14:02:15

    Spring을 시작한지 얼마 안되서.. 책을 보고 H2DB쓰는걸로 해서 DispatcherServlet 만들라길래 따라 만들고 공부했는데 그런 문제가 있었군요 .. Controller - Service - Repository 패턴의 레이어가 뭔지는 잘 모르겠지만 조금 더 공부해보도록 하겠습니다 답변 감사합니다!

    1
  • 로그인을 하시면 답변을 등록할 수 있습니다.