SSM 통합학습 BUG 요약

목차

一、결과 맵 컬렉션에는 이미 다음에 대한 값이 포함되어 있습니다...

2. org.apache.jasper.JasperException: TagLibraryValidator 클래스 로드 또는 인스턴스화 실패: [org.apache.taglibs.standard.tlv.JstlCoreTLV]

3. 브라우저는 페이지를 새로 고치지 않고 AJAX 요청을 보냅니다.

4. AJAX 요청과 함께 PUT 및 기타 요청을 직접 보내는 방법에 대한 문제


一、결과 맵 컬렉션에는 이미 다음에 대한 값이 포함되어 있습니다...

        이 예외의 이유

  • 리버스 엔지니어링 구성 문제
  • Spring 통합 MyBatis 구성 문제
  • 여러 세대의 리버스 엔지니어링으로 인해 코드 추가가 발생함
  • MyBatis 관련 파일은 targer 디렉터리에 패키지되어 있지 않습니다.

1. 먼저 리버스엔지니어링 생성 파일을 확인합니다.

        데이터베이스 연결 정보와 MyBatis 관련 파일 생성 전략이 올바르게 구성되어 있는지 주의하세요.

        동일한 이름을 가진 로컬 데이터베이스 테이블이 많이 있는 경우(기존 테이블이 이미 리버스 엔지니어링을 통해 해당 Bean을 생성했을 수 있음) 이번에 동일한 Bean을 생성하면 충돌이 발생하기 때문입니다.

        

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>

    <!--
            targetRuntime: 执行生成的逆向工程的版本
                MyBatis3Simple: 生成基本的CRUD(清新简洁版)
                MyBatis3: 生成带条件的CRUD(奢华尊享版)
    -->
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <!--设置生成出来的文件无注释信息-->
        <commentGenerator>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!-- 数据库的连接信息 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/ssm_crud?serverTimezone=UTC"
                        userId="......"
                        password="........">
        </jdbcConnection>
        <!-- javaBean的生成策略-->
        <javaModelGenerator targetPackage="com.pengpeng.crud.bean" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />  <!--enableSubPackages:是否可以生成子包-->
            <property name="trimStrings" value="true" />   <!--trimStrings:将表中的字段名前后空格截取生成对应的属性名-->
        </javaModelGenerator>
        <!-- SQL映射文件的生成策略 -->
        <sqlMapGenerator targetPackage="com.pengpeng.crud.dao" targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>
        <!-- Mapper接口的生成策略 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.pengpeng.crud.dao" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>
        <!-- 逆向分析的表 -->
        <!-- tableName设置为*号,可以对应所有表,此时不写domainObjectName -->
        <!-- domainObjectName属性指定生成出来的实体类的类名 -->
        <table tableName="t_emp" domainObjectName="Employee"/>
        <table tableName="t_dept" domainObjectName="Department"/>

    </context>

</generatorConfiguration>

2. Spring 구성 파일에서 MyBatis 통합과 관련된 구성을 확인합니다.

  • SqlSessionFactoryBean의 configLocation 속성(MyBatis 코어 구성 파일의 경로
    )의 속성 값이 올바르게 설정되어 있는지, 구성 파일 이름 앞에 Classpath를 추가해야 합니다.
  • SqlSessionFactoryBean의 데이터 소스를 설정해야 합니다.
  • 매퍼 매핑 파일이 있는 디렉터리 이름은 매퍼 인터페이스가 있는 디렉터리 이름과 일치해야 하며 MyBatis의 핵심 구성 파일에 있는 <mappers/> 태그로 지정되어야 합니다. SqlSessionFactoryBean의 mapperLocations 속성 구성 )
<!--配置 SqlSessionFactoryBean,可以直接在Spring的IOC容器中获取 SqlSessionFactory 对象-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--设置MyBatis核心配置文件的路径-->
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        <!-- 设置数据源 -->
        <property name="dataSource" ref="dataSource"></property>
<!--        &lt;!&ndash;指定mybatis,mapper文件位置&ndash;&gt;-->
<!--        <property name="mapperLocations" value="classpath:mappers/*.xml"></property>-->
    </bean>

    <!-- 配置一个可以执行批量的sqlSession -->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
        <constructor-arg name="executorType" value="BATCH"></constructor-arg>
    </bean>

    <!--
        配置mapper接口的扫描,可以将指定包下的所有的mapper接口
        通过IOC容器中已经配置好的SqlSessionFactoryBean所创建的sqlSession对象
        来为我们创建对应的代理实现类对象,并将这些对象交给IOC容器管理
    -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.pengpeng.crud.dao"></property>
    </bean>
  • 또한 매퍼 매핑 파일이 위치한 디렉터리의 이름이 매퍼 인터페이스가 있는 디렉터리의 이름과 일치하고 SqlSessionFactoryBean 및 매퍼 인터페이스의 스캐닝이 구성된 경우 다음 을 스캐닝하는 것으로 이해할 수 있습니다. 매퍼 인터페이스를 구성하면 이미 매퍼 구현 클래스 개체가 IOC에 저장됩니다. 컨테이너는 해당 매핑 파일을 관리하고 찾기 때문에 mapperLocations 속성을 구성할 필요가 없습니다.

3. 리버스 엔지니어링을 여러 번 생성

        역공학을 여러 번 생성할 경우 이전에 생성한 것을 완전히 삭제해야 하며, 그렇지 않으면 충돌이 발생하며, 다시 생성된 역공학도 반드시 확인해야 하며, 역공학 생성 시 코드가 추가되어 다수의 오류가 발생할 가능성이 있습니다. 반복되는 코드( 예: resultMap의 반복되는 id 속성 )는 한 번만 유지하면 됩니다 .

4. MyBatis 관련 파일은 targer 디렉터리에 패키지되어 있지 않습니다.

        MyBatis 관련 파일들이 targer 디렉터리에 패키징되어 있는지 확인하고, 그렇지 않다면 Maven 프로젝트를 Clear하고 다시 패키징한다.

2. org.apache.jasper.JasperException: TagLibraryValidator 클래스를 로드하거나 인스턴스화하지 못했습니다: [ org.apache.taglibs.standard.tlv.JstlCoreTLV ]

        이 오류는 jstl jar 패키지가 부족하여 발생할 수 있습니다.

        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

3. 브라우저는 페이지를 새로 고치지 않고 AJAX 요청을 보냅니다.

        이런 일이 발생하고 프런트엔드 및 백엔드 코드에 문제가 없다면 Ajax 요청의 경로와 매개변수에 주의해야 합니다. 공백이 있어서는 안 됩니다.

function to_page(pageNum) {
        $.ajax({
            url:"${APP_PATH}/emps",
            data:"pageNum=" + pageNum,
            type:"GET",
            success:function (result){
                //1、解析并显示员工数据
                build_emps_table(result)
                //2、解析并显示分页信息
                build_page_info(result)
                //3、解析分页条数据
                build_page_nav(result)
            }
        })
    };

        

4. AJAX 요청과 함께 PUT 및 기타 요청을 직접 보내는 방법에 대한 문제

REST 스타일 요청에서 업데이트 작업에 대한 요청 방법은 PUT이지만 Tomcat은 기본적으로 게시 요청만 구문 분석할 수 있습니다. 이 경우 실제 요청 방법을 나타내기 위해 요청 매개변수에 추가 " _method         " 매개변수를 전달해야 합니다. web.xml에 의해 전송된 후 사용됩니다. 에 구성된 HiddenHttpMethodFilter 필터에 의해 구문 분석됩니다.

        이때 AJAX를 사용하여 PUT 요청을 직접 보내는 경우 요청 본문에 데이터가 있지만 Bean 객체 데이터를 캡슐화할 수 없는 상황이 발생합니다 .

        직원[empId=1014, empName=null, 성별=null, 이메일=null, dId=null]

        이때 리버스 엔지니어링에 의해 자동 생성된 EmployeeMapper의 SQL은 다음과 같이 접합됩니다.

                emp_id = 1014인 경우 t_emp를 업데이트합니다.

그 이유는

        Tomcat이 데이터를 가져옵니다.

1. 요청 본문의 데이터를 맵으로 캡슐화합니다.

2. request.getParameter("empName")은 이 맵에서 값을 가져옵니다.

3. SpringMVC가 POJO 객체를 캡슐화할 때 request.getParamter("email");를 사용하여 POJO의 각 속성 값을 얻습니다.

        AJAX는 PUT 요청을 직접 보냅니다. 요청 본문의 데이터는 request.getParameter("empName")로 얻을 수 없습니다. Tomcat은 PUT 요청임을 확인하면 요청 본문의 데이터를 맵으로 캡슐화하지 않습니다. POST 형식의 요청만 캡슐화됩니다. 요청 본문은 맵입니다.

해결책

PUT과 같은 요청의 직접 전송을 지원하고 요청 본문에 데이터를 캡슐화할 수도 있어야 합니다.

1. web.xml에서 HttpPutFormContentFilter 필터를 구성합니다.

2. 역할: 요청 본문의 데이터를 구문 분석하고 맵으로 패키징합니다.

3. 요청이 다시 패키징되고, request.getParameter()가 다시 작성되며, 자체적으로 캡슐화된 맵에서 데이터를 가져옵니다.

<filter>
        <filter-name>HttpPutFormContentFilter</filter-name>
        <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
        <filter-name>HttpPutFormContentFilter</filter-name>
        <url-pattern>/*</url-pattern>
</filter-mapping>

추천

출처blog.csdn.net/weixin_64709241/article/details/128762819