SSM项目总结 和 个人错误总结

ssm-crud:SpringMVC+Spring+MyBatis

**功能**:对学生数据进行CRUD管理,分页,
		  数据校验(jQuery前端校验+Ajax校验+JSR303后端校验),
		  ajax数据传输,Rest风格的URI。
**技术点**:前端使用bootstrap构建 ,使用Ajiax传输数据;
		   后端使用SpringMVC + Spring + Mybatis
		   使用Maven进行项目管理 方便所需jar包的管理
		   分页:PageHelper
		   逆向工程:MyBatis Generator 方便实体类和mapper的创建

项目流程:
前端使用bootstrap,页面直接发送Ajax请求,由SpringMVC前端控制器进行拦截,判断需要进入哪个控制等的哪个方法体,然后控制层调用业务层的方法,业务层再调用Dao层,Dao通过Mybatis的mapper接口执行需要的sql对数据库进行操作。操作结束后返回JSON字符串,然后由js进行解析,使其在前端页面显示。
SpringMVC的Controller,Service,Dao由Springioc容器管理。通过@AutoWied进行自动注入。
Mybatis的mapper在项目启动时,mapper的实现类被扫描到ioc容器中。
Mybatis可以使用逆向工程Generator 生成Mapper接口,mapper文件,复杂的查询。
@RequestBody注解可以接收json格式的数据,并将其转换成对应的数据类型,在pom.xml中导入jackson-databind的依赖即可,如果未使用,会报500,类转换器找不到异常。
用户输入数据,并进行校验:1.JQuery前端校验 2ajax用户名重复校验,重要数据(后端校验(JSR303),唯一约束)。
错误集合(仅个人):
指定SpringMVC配置文件的两种方法:
1.在与web.xml同级的WEB-INF文件夹下创建一个+“-servlet”命名的XML文件,例如dispatcherServlet-servlet.xml

<servlet>
		<servlet-name>dispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>dispatcherServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

2.指定SpringMVC配置文件的位置,使用标签,并在pom.xml文件中配置扫描当前项目所有的XML文件。

 <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <!-- 指定SpringMVC配置文件 -->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <!--load-on-startup是启动顺序,让这个Servlet随Servlet容器一起启动。-->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
<!--扫描所有的xml文件-->
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>

AOP 织入切入点(txPoint)与事务增强(txAdvice)错误
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘departmentService’ defined in file [E:\IDEAworkplace\ssmcrud\out\artifacts\ssmcrud_war_exploded\WEB-INF\classes\com\atguigu\service\DepartmentService.class]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0’: Cannot resolve reference to bean ‘txPoint’ while setting bean property ‘pointcut’; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘txPoint’: Failed to introspect bean class [org.springframework.aop.aspectj.AspectJExpressionPointcut] for lookup method metadata: could not find class that it depends on; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0’: Cannot resolve reference to bean ‘txPoint’ while setting bean property ‘pointcut’; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘txPoint’: Failed to introspect bean class [org.springframework.aop.aspectj.AspectJExpressionPointcut] for lookup method metadata: could not find class that it depends on; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException
该错误是由于缺少aspectjweaver依赖导致,引入即可。

		<!--织入 缺少会报错-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.13</version>
        </dependency>

分页查询错误
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘departmentService’: Unsatisfied dependency expressed through field ‘departmentMapper’; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘departmentMapper’ defined in file [E:\IDEAworkplace\ssmcrud\out\artifacts\ssmcrud_war_exploded\WEB-INF\classes\com\atguigu\dao\DepartmentMapper.class]: Unsatisfied dependency expressed through bean property ‘sqlSessionFactory’; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘sessionFactory’ defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [mybatis-config.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error resolving class. Cause: org.apache.ibatis.type.TypeException: Could not resolve type alias ‘com.github.pagehelper.PageInterceptor’. Cause: java.lang.ClassNotFoundException: Cannot find class: com.github.pagehelper.PageInterceptor

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘departmentMapper’ defined in file [E:\IDEAworkplace\ssmcrud\out\artifacts\ssmcrud_war_exploded\WEB-INF\classes\com\atguigu\dao\DepartmentMapper.class]: Unsatisfied dependency expressed through bean property ‘sqlSessionFactory’; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘sessionFactory’ defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [mybatis-config.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error resolving class. Cause: org.apache.ibatis.type.TypeException: Could not resolve type alias ‘com.github.pagehelper.PageInterceptor’. Cause: java.lang.ClassNotFoundException: Cannot find class: com.github.pagehelper.PageInterceptor

分页查询的4.x与5.x的配置不一样 用法有所不同,并不是向下兼容,在使用5.x版本的时候可能会报错。
pagehelper4.x版本的使用com.github.pagehelper.PageHelper
agehelper5.x版本com.github.pagehelper.PageInterceptor

<dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.0.0</version>
        </dependency>
<plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!--分页参数合理化  -->
            <property name="helperDialect" value="mysql" />
            <property name="reasonable" value="true"/>
        </plugin>
    </plugins>
<dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>4.2.1</version>
        </dependency>
<plugins>
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <!--分页参数合理化  -->
            <property name="helperDialect" value="mysql" />
            <property name="reasonable" value="true"/>
        </plugin>
    </plugins>

类转换器找不到异常:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: No converter found for return value of type: class com.atguigu.beans.Msg

缺少jackson-databind依赖,该依赖会自动导入jackson-annontations和jackson-core包。

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.9</version>
        </dependency>

未知知识记录:
一、@PathVariable是spring3.0的一个新功能:接收请求路径中占位符的值
@PathVariable(“xxx”)
通过 @PathVariable 可以将URL中占位符参数{xxx}绑定到处理器类的方法形参中@PathVariable(“xxx“)
二、@RequestParam
GET和POST请求传的参数会自动转换赋值到@RequestParam 所注解的变量上
@RequestParam(org.springframework.web.bind.annotation.RequestParam)用于将指定的请求参数赋值给方法中的形参。
例如:

<form action="/WxProgram/json/requestParamTest" method="get">
    requestParam Test<br>
    用户名:<input type="text" name="username"><br>
    用户昵称:<input type="text" name="usernick"><br>
    <input type="submit" value="提交">
</form>
@RequestMapping(value="/requestParamTest", method = RequestMethod.GET)
    public String requestParamTest(@RequestParam(value="username") String userName, @RequestParam(value="usernick") String userNick){
        System.out.println("requestParam Test");
        System.out.println("username: " + userName);
        System.out.println("usernick: " + userNick);
        return "hello";
    }

也可不使用@RequestParam,直接接收,此时要求controller方法中的参数名称要跟form中name名称一致。

    @RequestMapping(value="/requestParamTest", method = RequestMethod.GET)
    public String requestParamTest(String username, String usernick){
        System.out.println("requestParam Test");
        System.out.println("username: " + username);
        System.out.println("usernick: " + usernick);
        return "hello";
    }

总结:
@RequestParam
用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容。提交方式为get或post。(Http协议中,如果不指定Content-Type,则默认传递的参数就是application/x-www-form-urlencoded类型)

RequestParam实质是将Request.getParameter() 中的Key-Value参数Map利用Spring的转化机制ConversionService配置,转化成参数接收对象或字段。

get方式中query String的值,和post方式中body data的值都会被Servlet接受到并转化到Request.getParameter()参数集中,所以@RequestParam可以获取的到。

三、@Valid

用于验证注解是否符合要求,直接加在变量employee之前,在变量中添加验证信息的要求,当不符合要求时就会在方法中返回Msg 的错误提示信息。

@RequestMapping(value = "/emp", method = RequestMethod.POST)
    @ResponseBody
    public Msg saveEmp(@Valid Employee employee, BindingResult result){
        if (result.hasErrors()){
            //校验失败,应该返回失败,在模态框中显示校验失败的错误提示
            HashMap<String, Object> map = new HashMap<>();
            List<FieldError> errors = result.getFieldErrors();
            for (FieldError fieldError: errors ) {
                System.out.println("错误的字段名" + fieldError.getField());
                System.out.println("错误信息" + fieldError.getDefaultMessage());
                map.put(fieldError.getField(), fieldError.getDefaultMessage());
            }
            return Msg.fail().add("errorFields", map);
        }else{
            employeeService.saveEmp(employee);
            return  Msg.success();
        }
    }

四、DepartmentExample的分析

DepartmentExample类中还包含了GeneratedCriteria、Criteria、Criterion三个静态内部类
Criterion表示一个最小粒度的条件的描述
GeneratedCriteria是一个抽象类;表示Criterion的集合,元素之间使用and连接
Criteria是GeneratedCriteria的实现类
DepartmentExample表示一个SQL语句的where、distinct、order by部分的描述;其中where部分表示Criteria的集合,元素间使用or连接

优点:

因为是代码生成的,可以省去自己写XML和接口方法
查询条件灵活

缺点:

查删改都需要使用Example,略显繁琐
没有分页功能

五:请求方式:GET&POST
详细讲解连接:https://blog.csdn.net/qq_42988711/article/details/102600788

将一个method定义成RequestMethod.GET时,可以直接通过地址访问,这非常方便我们在开发的时候调用到我们的接口并进行测试;

同样的接口,将其method更改为RequestMethod.POST时,你会发现接口在地址栏访问不了了,只有向服务器发起一个POST请求时才起作用。

GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。
POST方法向服务器提交数据,比如完成表单数据的提交,将数据提交给服务器处理。
PUT方法是让服务器用请求的主体部分来创建一个由所请求的URL命名的新文档;如果那个文档存在的话,就用这个主体来代替它。
**

GET在浏览器回退时是无害的,而POST会再次提交请求。

 

GET产生的URL地址可以被Bookmark,而POST不可以。

 

GET请求会被浏览器主动cache,而POST不会,除非手动设置。

 

GET请求只能进行url编码,而POST支持多种编码方式。

 

GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。

 

GET请求在URL中传送的参数是有长度限制的,而POST么有。

 

对参数的数据类型,GET只接受ASCII字符,而POST没有限制。

 

GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。

 

GET参数通过URL传递,POST放在Request body中。

**
GET和POST还有一个重大区别,简单的说:

GET产生一个TCP数据包;POST产生两个TCP数据包。

长的说:

对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);

而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

也就是说,GET只需要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。

因为POST需要两步,时间上消耗的要多一点,看起来GET比POST更有效。因此Yahoo团队有推荐用GET替换POST来优化网站性能。但这是一个坑!跳入需谨慎。为什么?

  1. GET与POST都有自己的语义,不能随便混用。

  2. 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。

  3. 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深红十二连丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值