ssm学习的一点笔记

常用依赖

<dependencies>    
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <!--spring依赖包-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.0.RELEASE</version>
    </dependency>
    <!--spring连接MySQL的依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.2.0.RELEASE</version>
    </dependency>
    <!-- aspectj切面-->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.4</version>
    </dependency>
    <!--mybatis-spring整合包-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.5</version>
    </dependency>
    <!--servlet,有tomcat依赖包时不需要导入servlet的依赖-->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>


    <!--mysql驱动8.0.11-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.11</version>
        <scope>compile</scope>
    </dependency>
    <!--druid连接池-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.22</version>
    </dependency>
    <!--jstl依赖-->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <!--servlet系列:servlet\jsp\jstl-->
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet/jsp-api -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>


    <!--json数据处理-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.59</version>
    </dependency>
    <!--mysql驱动5.1.6-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.6</version>
    </dependency>
    <!--mybatis-->
    <dependency>
       <groupId>org.mybatis</groupId>
       <artifactId>mybatis</artifactId>
       <version>3.5.2</version>
    </dependency>
    <!--log4j,日志-->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.12</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
    <!--自动配置实体类-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
        <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->  
    <!--jackson,json数据解析工具-->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.11.0</version>
    </dependency>
</dependencies>

###mybatis-config.xml配置
数据库连接后面会放到spring中实现

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>

手动实现代理

利用反射
public class ProxyInvocationHandler implements InvocationHandler {
    private Object target;
    //设置真实用户
    public void setTarget(Object target) {
        this.target = target;
    }
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        seeHouse();
        //这里是通过反射执行被代理对象的业务
        Object result=method.invoke(target,args);
        return result;
    }
    //这里是代理的业务
    public void seeHouse(){
        System.out.println("看房");
    }
}

###maven中静态资源和字节码文件的过滤
配置mapper时碰到XXXmapper.xml不输出到target的问题
问题报错

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.ysq.mapper.UserMapper.queryAllUser

解决方法,在pom.xml中配置

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
</build>
@Autowired 注入失效问题

使用Junit测试时,如果需要使用上下文context(比如自动注入),必须指定spring环境
注:Junit版本需要4.12以上

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})

404警告

The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.

根据教程,一开始以为是没配 lib,配了之后还是这个错误,后来才发现Controller没实例化,尴尬了
 <bean id="/hello" class="com.ysq.controller.HelloController"/>

springMVC的快速搭建

准备工作:

添加web支持(javaEE 4+);
导入所有jar包到lib

  1. 配置Web.xml
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

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

2.配置springmvc-servlet

    <context:component-scan base-package="com.ysq.*"/>
    <!--不过滤静态文件-->
    <mvc:default-servlet-handler/>
    <!--启动RequestMapping注解-->
    <mvc:annotation-driven/>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          id="internalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

3.创建Controller(注解方式)

@Controller
public class HelloController {
    @RequestMapping("/hello")
    public String hello(Model model){
        //封装数据
        model.addAttribute("msg","hello Shane!!");
        return "hello";
    }
}

4.根据请求跳转页面
jsp、HTML之类的页面

@RequestMapping的注意点

  • 在类上注解和方法上注解
    类上注解的路径会成为所有方法的父路径
    以下路径会是:/calculate/add、/calcaulate/sub
@Controller
@RequestMapping("/calculate")
public class ResFullController {
   @RequestMapping("/add")
   public String getAdd(Model model){
       model.addAttribute("result",a+b);
       return "result";
   }
   @RequestMapping("/sub")
   public String getAdd(Model model){
       //model.addAttribute("result",a+b);
       //...
       return "result";
   }
}
  • 路径参数
@RequestMapping("/add/{a}/{b}")
    public String getAdd(@PathVariable int a,@PathVariable int b, Model model){
        model.addAttribute("result",a+b);
        return "result";
    }
  • 请求方式
    通过参数method:GET、POST、PUT、DELETE
@RequestMapping(path="/add/{a}/{b}",method = RequestMethod.DELETE)
    public String getAdd(@PathVariable int a,@PathVariable int b, Model model){
        model.addAttribute("result",a+b);
        return "result";
    }
  • 请求方式另一种方式是使用注解
    @GetMapping("…")、@DeleteMapping("…")
    可以实现同一路径不同方法
    @GetMapping("/sub/{a}/{b}")
    public String Sub(@PathVariable int a,@PathVariable int b,Model model){
        model.addAttribute("result",a-b);
        return "result";
    }
    @PostMapping("/sub/{a}/{b}")
    public String Sub2(@PathVariable int a,@PathVariable int b,Model model){
        model.addAttribute("result",b-a);
        return "result";
    }

MarkDown快速使用

网页乱码问题

使用过滤器Filter解决
1.添加过滤器

public class EncodingFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("UTF-8");
        servletResponse.setCharacterEncoding("UTF-8");
    }

    public void destroy() {

    }
}

2.配置到web.xml

 <filter>
        <filter-name>filter</filter-name>
        <filter-class>com.ysq.filter.EncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filter</filter-name>
        <url-pattern>/</url-pattern>
    </filter-mapping>

3.以上的方法只能解决GET方式下的乱码,POST方式请求仍然报错
尝试使用spring自带的过滤器,还是解决不了POST请求

<filter>
        <filter-name>encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/</url-pattern>
    </filter-mapping>

4.最后仔细看一下才发现写错了
这里应该用 /* 表示过滤所有jsp,而不是 /

<filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

###只请求数据,不需要转到视图时
使用@ResponseBody

    @RequestMapping("/json")
    @ResponseBody   //直接返回值,而不是导向视图解析器
    public String getJSon(){
        User user=new User();
        return "json";
    }

或者直接在类上添加注解@RestController
这个时候也不需要写@Controller,相当于把这个Controller类当做数据请求中心,一般在严格的前后端项目中使用

@RestController
public class userController {
    @RequestMapping(value = "/json")
    public String getJSon() throws JsonProcessingException {
        User user=new User(12,"你好,Shane",18);
        ObjectMapper mapper=new ObjectMapper();
        return mapper.writeValueAsString(user);
    }
}

json数据乱码问题

  • 第一种方法是在RequestMapping中设置produces
    但是这种方法需要在每一个地方都设置,十分麻烦
@RequestMapping(value = "/json",produces = "application/json;charset=utf-8")
  • 第二种方法是在spring-servlet.xml中统一设置
    ps: json字符串会直接转换为json对象,可以在js中使用
  <mvc:annotation-driven>
          <mvc:message-converters>
              <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                  <property name="supportedMediaTypes">
                      <list>
                          <value>application/json;charset=UTF-8</value>
                      </list>
                  </property>
              </bean>
          </mvc:message-converters>
      </mvc:annotation-driven>

使用Jackson实现的一个快速工具类

  • 重点在于使用ObjectMapper吧对象转换为json字符串
  • 如果直接把Date 日期类型的对象传到前端,前端只能得到一个时间戳,
    所以需要通过关闭时间戳模式和设置日期格式来获取想要的字符串。
public class JsonUtil {
    public static String getJson(Object object){
        ObjectMapper mapper=new ObjectMapper();
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
        SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
        mapper.setDateFormat(format);
        try {
            return mapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static String getJson(Object object,String dateformat){
        ObjectMapper mapper=new ObjectMapper();
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
        SimpleDateFormat format=new SimpleDateFormat(dateformat);
        mapper.setDateFormat(format);
        try {
            return mapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}

c3p0连接池xml常用配置

<context:property-placeholder location="classpath:database.properties"/>
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!-- 配置连接池属性 -->
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>

        <!-- c3p0连接池的私有属性 -->
        <property name="maxPoolSize" value="30"/>
        <property name="minPoolSize" value="10"/>

        <!-- 关闭连接后不自动commit -->
        <property name="autoCommitOnClose" value="false"/>

        <!-- 获取连接超时时间 -->
        <property name="checkoutTimeout" value="10000"/>

        <!-- 当获取连接失败重试次数 -->
        <property name="acquireRetryAttempts" value="2"/>
    </bean>

SSM整合

spring-dao.xml配置

<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/context/spring-context.xsd">
    <context:property-placeholder location="classpath:database.properties"/>
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!-- 配置连接池属性 -->
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>

        <!-- c3p0连接池的私有属性 -->
        <property name="maxPoolSize" value="30"/>
        <property name="minPoolSize" value="10"/>

        <!-- 关闭连接后不自动commit -->
        <property name="autoCommitOnClose" value="false"/>

        <!-- 获取连接超时时间 -->
        <property name="checkoutTimeout" value="10000"/>

        <!-- 当获取连接失败重试次数 -->
        <property name="acquireRetryAttempts" value="2"/>
    </bean>
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!--绑定mybatis配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--注入sqlSessionFactory-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--扫描dao包-->
        <property name="basePackage" value="com.ysq.mapper"/>
    </bean>
</beans>

spring-service.xml配置

  <!--扫描所有service类-->
    <context:component-scan base-package="com.ysq.service"/>
    <!--将业务类注入到spring-->
    <bean id="UserServiceImpl" class="com.ysq.service.UserServiceImpl">
        <property name="userMapper" ref="userMapper"/>
    </bean>
    <!--声明事务配置-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
   <!-- AOP横切事务-->

SSM整合报错
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.ysq.service.UserService' available

找不到Service的Bean,但是在Test中通过ApplicationContext可以正常使用Bean。
可以确定时spring的问题,与底层无关。
经过检查,发现是web.xml中配错了,之前按习惯配了spring-mvc.xml,但是整合之后应该使用application-context.xml

<init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:application-context.xml</param-value>
        </init-param>

横切事务提交

对数据库进行更新、删除操作时,事务不会自动提交,必须手动提交

   <!-- AOP横切事务-->
    <!--配置事务通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!--给方法配置事务-->
        <tx:attributes>
            <tx:method name="add" propagation="REQUIRED"/>
            <tx:method name="delete" propagation="REQUIRED"/>
            <tx:method name="query" read-only="true"/>
            <tx:method name="update" propagation="REQUIRED"/>
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
    <!--配置事务切入-->
    <aop:config>
        <aop:pointcut id="txPointcut" expression="execution(* com.ysq.mapper.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
    </aop:config>

##事务提交失败

  • 从前端提交到后端时取到的实体类对象时没有id字段的
//修改用户
    @RequestMapping("/UpdateUser")
    public String UpdateUser(User user){
        userService.updateUser(user);
        return "redirect:/user/allUsers";
    }
  • 解决方案:
    前端传递隐藏域,例如:
<input type="hidden" value="${user.id}">

restFull实例

直接在地址栏中通过地址的方式传递参数

@RequestMapping(method = RequestMethod.POST, value = "/user/{id}")
    public String delUser(@PathVariable("id") String uid) {
        System.out.println("del:" + uid);
        return "success";
    }
注意使用jsp时必须在头部添加以下代码,否则foreach不会遍历

<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>

后端接收前端json数据失败

采用了@ResponseBody和@RequestBody,想要获取前端json数据直接转换为实体类对象。
前端

$.post({
    url: url,
    contentType:"application/json;charset=utf-8",
    data: jsondata,
    success: function (data) {
        console.log(data);
        layer.close(index1);
        layer.close(index2);
        var msg=layer.open({
            title: false
            ,icon:1
            ,btn:"返回"
            ,content: '已完成'
            ,yes:function () {
                layer.close(msg)
                //$(location).attr("href", "${pageContext.request.contextPath}/user/toIndex")
            }
        });
    }

后端

 @RequestMapping(value = "/updateAppVersion",produces = "application/json;charset=utf-8")
    @ResponseBody
    public String UpdateAppVersion(HttpSession session,@RequestBody AppVersion appVersion){
       ///....
        return JSON.toJSONString(success);
    }
  • 主要报错415,webType不支持之类的错误
  • 这个问题搞了好久,检查过contentType和application/json之类的都写了。
  • 查了好久,最后加上了Jackson依赖才终于正常运行,
    看资料应该是因为RequestBody注解想要把json数据转换为实体类对象,就需要用到Jackson的方法。
<dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.11.0</version>
    </dependency>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值