초보자 웹 개발 단순 요약 (10 개)-데이터베이스 HSQLDB 인스턴스 문제 요약

 

목차

하나의 문제 요약

1. Book 및 DbOperation과 같은 JavaBeans 인스턴스화

질문 1 : @ComponentScan에는 스캔 범위가 있습니다.

질문 2 : HttpServlet에서 @Autowired 주석이 달린 인스턴스를 사용하여 "NullPointerException"보고

2. EL 표현

질문 1 : c : foreach 사용

질문 2 : $ () 사용은 항상 유효하지 않습니다.

3. JDBC

두 번째 요약


Xiaobai (8) -Database HSQLDB 인스턴스초보자 웹 개발 에 대한 간단한 요약예제 의 코드는 여러 문제를 반복해서 해결 한 후 성공적으로 프로젝트를 실행할 수있는 최종 코드입니다.이 코드는 요약의 초점이 아닙니다. Android 개발이기 때문에 자바 코드를 작성하는 것은 너무 간단합니다. 주로이 과정에서 발생하는 문제를 요약하고 웹 개발에 대해 더 깊은 인상을 드리고 싶습니다. 물론 몇 가지 질문이 있습니다. , 나중에 가야합니다. 하나씩 해결하세요. 이 기사는 주로 발생한 문제 중 일부를 요약하기위한 것입니다.

하나의 문제 요약

1. Book 및 DbOperation과 같은 JavaBeans 인스턴스화

이러한 JavaBean 중 일부에는 종속성이 있으므로 이러한 JavaBeans의 인스턴스화 및로드 관리 프로세스가 포함됩니다 .Xiaobai의 초보자 웹 개발 에 대한 간단한 요약 에서 배울 수 있다고 생각하기 쉽습니다 (6)- Spring IoC 컨테이너 는 이러한 JavaBeans를 관리하는 주석이 달린 방법을 언급했습니다.

이전 누적으로 인해 가장 먼저 떠오르는 것이 JavaBeans 관리를위한 Spring입니다. AnnotationConfigApplicationContext를 인스턴스화하고 웹 애플리케이션이 시작될 때 인스턴스화해야합니다. 다음과 같이 ServletContextListener 클래스 구현을 생각하는 것은 당연합니다.

@Configuration
@ComponentScan //扫描所在类的包以及子包,来创建@Component的类
public class SpringContextListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("SpringContextListener context Initialized!!! ");
        // bookManagerService.createBookTable();
        //初始化所有的@Component的类
        new AnnotationConfigApplicationContext(SpringContextListener.class);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("SpringContextListener context Destroyed!!! ");
    }
}

이 코드를 통해 웹 애플리케이션이 시작되면 AnnotationConfigApplicationContext가 초기화되고 @Component, @Autowired 등의 어노테이션을 사용할 수 있으며 리스너도 web.xml에서 구성해야한다고 생각합니다.

    <listener>
         <listener-class>com.wj.hsqldb.SpringContextListener</listener-class>
    </listener>

모든 것이 제자리에 있고 성공적인 운영 프로젝트가 완료 될 수 있다고 생각했지만 여러 가지 문제가 뒤따를 것이라고는 결코 예상하지 못했습니다.

질문 1 : @ComponentScan에는 스캔 범위가 있습니다.

먼저 Book, DbOperation, JdbcConfiguration 및 BookManagerService의 네 가지 클래스에 대해 썼습니다 .HSQLDB 데이터베이스의 추가, 삭제 및 수정의 정확성을 확인하기 위해 SpringContextListener에 testDb () 메서드를 추가했습니다. 자세한 코드는 The details를 참조하십시오. com.wj.hsqldb.listener.SpringContextListener의 코드에서 예기치 않게 다음 오류가보고되었습니다.


rg.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.wj.hsqldb.db.JdbcConfiguration' available
		at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:354)
		at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:345)
		at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1126)
		at com.wj.hsqldb.model.SpringContextListener.testDb(SpringContextListener.java:44)
		at com.wj.hsqldb.model.SpringContextListener.contextInitialized(SpringContextListener.java:29)
		at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4716)
		at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5177)
  • 문제 분석

위의 오류에 대한 일반적인 분석은 @Component, @Autowired 이러한 주석이 유효하지 않다는 것일 수 있습니다. @ComponentScan에 스캔 범위가 있다는 것을 갑자기 기억하고 클래스가 위치한 패키지와 하위 패키지 아래의 클래스를 다음과 같이 스캔합니다. 내 현재 프로젝트 구조는 다음과 같습니다.

이제 SpringContextListener가 com.wj.hsqldb.listener 패키지 아래에 배치되었으므로 어떻게 다른 클래스를 스캔 할 수 있습니까?

  • 해결책:

SpringContextListener 클래스의 @ComponentScan을 @ComponentScan ( "com")으로 수정합니다 . 프로젝트를 다시 실행하면 홈 페이지 콘텐츠가 성공적으로 나타납니다.

질문 2 : HttpServlet에서 @Autowired 주석이 달린 인스턴스를 사용하여 "NullPointerException"보고

데이터베이스의 추가, 삭제, 수정에 오류가 없는지 확인한 후 HttpServlet 코드를 차례로 추가하기 시작했는데 일반적인 아이디어는 코드를 구현하는 것입니다.


@WebServlet(name = "BookListServlet", value = "/booklist")
public class BookListController extends HttpServlet {
    @Autowired
    public BookManagerService bookManagerService;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        List<Book> books = bookManagerService.getBook();
        System.out.println("book size = " + books.size());
        req.setAttribute("book", books);
        req.getRequestDispatcher("/book/booklist.jsp").forward(req, resp);
    }
}

이제 모든 JavaBeans를 Spring과 함께로드 할 수 있으므로 HttpServlet에서 이러한 JavaBeans를 직접 사용할 수 있다고 생각했지만 다음 오류를보고 할 것으로 예상하지 못했습니다.

  • 문제 분석

문제는 매우 간단합니다. 즉, bookManagerService가 인스턴스화되지 않았습니다 .BookManagerService의 초기화 메서드 (@PostConstruct로 표시됨)에서 JavaBean도 인스턴스화되었음을 발견했지만 HttpServlet이 널 포인터를보고하는 이유는 무엇입니까?

  • 해결책

나중에 다양한 자료를 확인하고 그 이유의 본질을 찾았습니다. 이러한 HttpServlet은 Servlet 컨테이너에서 인스턴스화되고 BookManagerService와 같은 JavaBean은 Spring IoC 컨테이너에서 인스턴스화되므로이 JavaBean 인스턴스는 HttpServlet에서 얻을 수 없습니다. 인터넷에서 HttpServlet의 init (config) 메서드를 다시 작성하고 다음 코드를 추가하는 몇 가지 솔루션을 보았습니다.

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        ServletContext application = this.getServletContext();     
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,application);
    }

예기치 않게 여기에서 다시 예상치 못한 일이 발생했으며 다음 오류가보고되었습니다.

이전 요약 에서 초보 웹 개발 에 대한 간단한 요약을 즉시 생각했습니다. (2) -web.xml에서 ContextLoaderListener의 역할은 무엇입니까?이 ContextLoaderListener는 웹 응용 프로그램이 시작될 때 contextConfigLocation에서 지정한 구성 파일을 자동으로 읽습니다. ApplicationContext가 어셈블되고이 ApplicationContext는 Spring의 IoC이며 ApplicationContext는 ServletContext에 바인딩됩니다. 그래서 의도적으로 ContextLoaderListener의 소스 코드를 연구했습니다. Xiaobai 초보자 웹 개발 요약 요약 (9) -ContextLoaderListener를 참조하십시오 .

따라서이 문제 2에 대한 궁극적 인 해결책은 첫 번째 부분입니다. web.xml에 ContextLoaderListener 리스너를 도입하는 것입니다.

    <!--用来配置Spring的配置文件-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:config/application-context.xml</param-value>
    </context-param>
<!--    用来创建Spring的IoC容器,并完成与ServletContext的绑定-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

이 리스너를 도입하는 것만으로는 궁극적으로이 문제를 해결할 수 없습니다. 소스 코드에서 이러한 JavaBeans는 기본적으로 구성 파일을 통해 구성되어 있음을 알 수 있습니다. 처음에는 구성 파일을 통해 <bean>을 추가했지만 여전히 이와 같은 문제가 있습니다. . 처음 Spring MVC와 접촉했을 때 @Controller, @Autowired 및 기타 주석을 직접 사용할 수 있었기 때문에 노력이 결실을 맺고 마침내 솔루션의 두 번째 부분을 찾았습니다 . contextConfigLocation 다음 내용이 파일에 추가됩니다.

<?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 https://www.springframework.org/schema/context/spring-context.xsd">
    <!--可通过注解配置JavaBean-->
    <context:annotation-config/>
    <context:component-scan base-package="com.wj"/>
</beans>

이때 @Controller와 @Autowired는 HttpServlet이 아닌 곳에서도 사용할 수 있습니다. 문제는 없지만 Serlvet 컨테이너에서 JavaBean을 사용하는 문제는 아직 해결되지 않았습니다. 해결 방법의 세 번째 부분 인 init 다시 작성 이 필요합니다. (HttpServlet 구성)) Method , 다음 코드를 추가하십시오.

    @Override

    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        ServletContext application = this.getServletContext();    
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,application);
    }

위의 세 부분을 거쳐 마침내이 문제가 해결됩니다. 2 : HttpServlet의 @Autowired 주석 인스턴스가 "NullPointerException"으로보고됩니다.

2. EL 표현

질문 1 : c : foreach 사용

c : foreach를 사용할 때 원하는 효과를 얻지 못했습니다.

  • 문제 원인

.jsp 파일은 c : foreach를 사용하는 것과 같은 Android 개발과 다른 점이 있습니다. tablib는 처음에 도입되지 않았기 때문에이 태그를 사용할 때 작동하지 않았지만 컴파일 오류를보고하지 않지만 프로젝트가 성공적으로 실행되지 않습니다. .

  • 해결책

나중에 다양한 자료를 검색 한 결과 .jsp 파일에서 목록 모음을 만드는 루프가 c : foreach를 사용하는 것을 발견했습니다. 나중에 이런 종류의 c : foreach를 사용하려면 tablib 태그를 도입해야한다는 것을 알게되었습니다.

첫 번째 부분 : c 태그 소개에서 .jsp 파일에 다음 코드를 추가해야합니다.

<%--需要导入C标签该包--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

2 부 : pom.xml에 다음 종속성을 추가합니다.

 <!-- 与jsp中的C标签相关的依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>

이 두 부분의 구성을 통해 .jsp 파일에서 c : foreach를 사용할 수 있습니다.

질문 2 : $ () 사용은 항상 유효하지 않습니다.

$ {}는 .jsp에서 해당 필드의 내용을 쉽게 가져올 수 있지만 해당 필드의 내용을 항상 읽을 수는 없습니다. 예를 들어 이전에 booklist.jsp에 다음 코드가 있습니다.

<%

    List books = (List) request.getAttribute("book");
    boolean isEmpty = books.isEmpty();
    String display = isEmpty ? "none" : "block"; //display: ${display}

%>   
<table>
 <c:forEach items="${book}" var="it">

        <tr style="color: red;alignment: center">
            <td>${it.id}</td>
            <td>${it.name}</td>
            <td>${it.price}</td>
            <td>${it.online}</td>
        </tr>
    </c:forEach>
</table>
  • 문제 분석

잘못된 사용 방법으로 인해 발생해야합니다.

  • 해결책

BookListController가 .jsp 파일로 점프하면 setAttribute를 통해 속성으로 직접 설정됩니다.

      req.setAttribute("book", books);
      req.getRequestDispatcher("/book/booklist.jsp").forward(req, resp);

EL은 요청, 세션, 페이지 및 응용 프로그램에서만 속성을 가져올 수 있으며 4 개의 도메인에 작성된 키에서 콘텐츠를 직접 읽을 수 있습니다.

(1) 도메인 속성 관련

requestScope : $ {requestScope.name}과 같은 요청 범위 또는 도메인 속성 공간에서 해당 키를 찾습니다.

sessionScope : $ {sessionScope.name}과 같은 세션 범위 또는 도메인 속성 공간에서 해당 키를 찾습니다.

pageScope : $ {pageScope.name}과 같은 pageScope 범위 또는 도메인 속성 공간에서 해당 키를 찾습니다.

applicationScope : $ {applicationScope.name}과 같은 애플리케이션 범위 또는 도메인 속성 공간에서 해당 키를 확인합니다.

이러한 키에 해당하는 내용은 setAttribute ( "key", "value")를 통해 해당 필드에 작성되어야합니다.

(2) 기타 개체

pageContext : jsp의 내장 pageContext와 동일한 객체입니다. 이 객체를 통해 요청, 응답, 세션, servletContext 및 기타 객체를 가져올 수 있습니다. 예를 들어 $ {pageContext.request}를 통해 요청 객체를 직접 가져오고 $ {pageContext.request를 통해 웹 응용 프로그램의 루트를 가져올 수 있습니다. contextPath}, 바로 뒤에 점프 경로를 추가 할 수 있습니다.


<form action="${pageContext.request.contextPath}/addbook" method="get">
 
</form>

그리고 초보 웹 개발 (8 개) 데이터베이스 HSQLDB 인스턴스 예제 간단한 요약에서 얻은 값은 ""입니다.

param : $ {param.name}과 같이 request.getParameter ()에 해당하는 가져온 요청의 지정된 매개 변수

paramValues ​​: request.getParameterValues ​​()와 동등한 요청의 지정된 매개 변수 색인 값을 가져옵니다.

EL 표현식의 한계로 인해 이러한 로직은 종종 .jsp에 Java 코드를 추가하여 직접 구현할 수 있습니다.

3. JDBC

JDBC (Java DataBase Connectivity). Java가 데이터베이스에 액세스하기위한 표준 인터페이스입니다. 많은 애플리케이션이 데이터베이스에 직접 액세스하고 다른 데이터베이스 공급 업체에서 제공하는 데이터베이스와 호환되기 위해 모두 JDBC 인터페이스를 통해 데이터베이스에 액세스합니다. 데이터베이스 제조업체는 JDBC 드라이버를 제공합니다. 이러한 JDBC 드라이버에는 네트워크 및 기본 네트워크 통신을 통해 데이터베이스에 액세스하는 논리가 포함되어 있으므로 웹 응용 프로그램이 JDBC 인터페이스를 통해 JDBC 드라이버에 직접 액세스하여 데이터베이스 액세스를 완료 할 수 있습니다.

JDBC 트랜잭션 : 데이터베이스의 트랜잭션은 일련의 작업을 형성하는 여러 SQL 문으로 구성됩니다. 즉, 일부 비즈니스 요구 사항에서 일련의 SQL 문을 실행해야합니다. SQL 문 실행에 오류가 있으면 모든 SQL을 취소해야합니다. 따라서 이러한 여러 SQL 문을 전체적으로 실행해야합니다. 거래라고합니다. 데이터베이스 시스템은 트랜잭션의 모든 SQL이 실행되거나 전혀 실행되지 않도록 보장합니다.

두 번째 요약

Xiaobai (8) 데이터베이스 HSQLDB 인스턴스의 초보 웹 개발 에 대한 간단한 요약, 간단한 예제 및 웹 애플리케이션 개발에 대한 새로운 이해를 통해 :

1. 웹 애플리케이션 개발은 Spring의 IoC 컨테이너를 초기화하고 컨테이너를 SerlvetContext에 바인딩하기 위해 web.xml에서 ContextLoaderListener를 구성해야합니다.

2. <context : annotation-config />를 추가하여 주석을 통해 JavaBeans를로드 및 관리 할 수 ​​있으며 스캔 된 패키지를 설정하도록 <context : component-scan base-package = "com.wj"/>를 구성 할 수 있습니다.

3. Spring에 의해 인스턴스화 된 JavaBean 객체는 두 가지 다른 것이므로 HttpServlet에서 직접 사용할 수 없습니다. 그러나 주석은 SpringBeanAutowiringSupport.processInjectionBasedOnServletContext ()를 통해 ServletContext에 바인딩 될 수 있습니다.

4. EL 표현식은 요청, 세션, 페이지 및 애플리케이션에 의해 설정된 속성 값만 얻습니다.

5. @ComponentScan에는 스캔 범위가 있으므로 @ComponentScan ( "패키지 이름")으로 스캔 패키지 범위를 직접 설정할 수 있습니다.

6. c 태그는 jsp에 도입되어야 할뿐만 아니라 c 태그를 사용하기 전에 종속성에 추가해야합니다.

물론 몇 가지 문제가 남아 있습니다.

1. .jsp의 일부 파일은 너무 표준화되지 않았으므로 나중에 연구해야합니다.

2. 이러한 더 나은 프레임 워크는 DbOperation, Book 및 기타 클래스를 대체해야합니다.

3. 링크 닫기 등과 같은 데이터베이스 리소스 관리에주의를 기울이지 않았습니다.

4. xml에서 <bean>을 구성하여 JavaBeans를로드하고 관리하는 방식에서도 검증 전에 발생하는 문제가 있습니다.

다음 기사는 Xiaobai (11) 관련 데이터베이스 연결 최적화 (DataSource)의 초보 웹 개발에 대한 간단한 요약입니다. 

추천

출처blog.csdn.net/nihaomabmt/article/details/114287378