Fork me on GitHub

ssm知识点和问题

前言

主要用来记录学习ssm框架中所遇到的一些知识点和遇到的问题(不定时更新)
若对其中一些代码举例不太清楚的,可以参考ssm简单使用

ssm知识点

ssm框架对应的Java开发三层架构

spring作用

@RequestMapping注解方式作用

  • url映射

    设置controller方法对应的url,运行处理器映射时使用
    
  • 窄化请求映射

    为了便于对url进行分类管理,可以对controller类上定义url,相当于访问路径的根目录
    
  • 限制http请求方法

    除了定义url路径外,还可以限制http请求方法,格式如下:
    @RequestMapping(value="请求路径",method = {请求方法1,请求方法2}),
    比如说:RequestMethod.POST表示post请求方法
    若只设置了post请求,则只能以post请求访问
    

controller返回类型

  • 返回ModelAndView
    在controller类的方法中创建视图对象并返回视图对象
    下面的例子是参照ssm简单使用中的ItemsController来写的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @RequestMapping("/queryItems")
    public ModelAndView queryItems() throws Exception{
    //调用service来显示商品列表
    List<ItemCustom> itemsList=itemsService.findItemsList(null);

    ModelAndView modelAndView=new ModelAndView(); //创建视图对象
    modelAndView.addObject("itemsList",itemsList);
    modelAndView.setViewName("itemsList"); //指定用户访问的jsp页面地址,前缀和后缀已在前端控制器中配好
    return modelAndView;
    }
  • 返回string
    1.返回的是逻辑视图名,真正的视图路径=前缀+逻辑视图名+后缀(也就是jsp页面路径)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
       @RequestMapping("/editItems")
    public String editItems(Model model) throws Exception{
    //String返回的是逻辑视图名
    //直接指定返回id为1的商品信息
    ItemCustom itemCustom=itemsService.findItemsById(1);
    //使用形参中的Model来实现ModelAndView的效果
    model.addAttribute("itemCustom",itemCustom);


    return "editItems";
    }

2.redirect重定向
在返回String的同时,可以进行页面的重定向操作,此时地址栏url会发生变化,并且修改提交的request数据无法传到重定向的地址

1
2
3
4
5
6
7
8
@RequestMapping("/editItemsSubmit")
public String editItemsSubmit() throws Exception{
//重定向操作
//提交修改信息后重定向到查询列表页面
//格式为
// return "redirect:path";
return "redirect:queryItems.action";
}

3.forward页面转发
通过forward进行转发时,地址栏url不会发生变化,同时request数据可以传到转发的地址处(将上面代码中的redirect改为forward就可以了)

  • 返回void
    返回这种结果的时候可以在Controller方法的形参中定义HTTPServletRequest和HTTPServletResponse对象进行请求的接收和响应

    1.使用request转发页面

    1
    2
    3
    public void 方法名(HttpServletRequest request, HttpServletResponse response) throws Exception{
    request.getRequestDispatcher("转发路径").forward(request,response);
    }

    2.使用response进行重定向

    response.sendRedirect("重定向路径");
    

    3.使用response响应结果(设置编码格式,json串之类的)

    response.setCharacterEncoding("UTF-8");
    response.setContentType("application/json;charset=utf-8");
    response.getWriter.write("json串");
    

controller参数绑定

过程是从客户端请求key/value数据,通过转换,将key/value数据转换结果绑定到controller方法的形参上。
springmvc中,通过方法形参来接收页面数据,而不是在controller中定义成员变量接收
参数绑定

controller参数绑定默认支持的类型

在controller方法形参上定义下边几种类型的对象,则在参数绑定过程中可以直接绑定对应的参数

  • HttpServletRequest

    通过request对象获取请求信息
    
  • HttpServletResponse

    通过response对象处理响应信息
    
  • HttpSession

    通过session对象得到session中存放的数据
    
  • Model/ModelMap

    Model:包含四个addAttribute 和一个merAttribute方法的接口,
    ModelMap: 实现了Map接口,包含Map方法。视图层通过request找到ModelMap中的数据,    
    两个类型的用法都差不多,作用是将model中的数据存放到request域
    
  • 简单数据类型
    即Integer,String等类型,可以通过@RequestParam的注解方式来绑定参数
    若不使用,则需要保证controller形参和request传入参数名称一致
    @RequestParam格式如下:

    @RequestParam(value="指定参数",required=true/false,defaultValue="默认值")
    value中设置request传入的指定参数名
    required设置是否必须传参,true为必须传参,false为不必须
    defaultValue设置参数默认值
    

    不使用@RequestParam时

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      @RequestMapping(value="/editItems",method = {RequestMethod.POST,RequestMethod.GET})
    public String editItems(Model model,Integer id) throws Exception{
    // 调用service通过id查找相应的商品信息
    // 这里需要进行绑定参数的设置
    // 由于request传入的名称为id,这里必须将形参的名称设置为id
    ItemCustom itemCustom=itemsService.findItemsById(id);
    model.addAttribute("itemCustom",itemCustom);
    return "editItems";

    }

    使用@RequestParam时

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      @RequestMapping(value="/editItems",method = {RequestMethod.POST,RequestMethod.GET})
    public String editItems(Model model,@RequestParam(value="id") Integer item_id) throws Exception{
    // 调用service通过id查找相应的商品信息
    // 这里需要进行绑定参数的设置
    // 若这里设置了defaultValue=“2”, 则在不传id的情况下默认传id=2的数据
    ItemCustom itemCustom=itemsService.findItemsById(item_id);
    model.addAttribute("itemCustom",itemCustom);
    return "editItems";

    }

    即在相应的形参面前进行@RequestParam注解,就可以自由定义形参的名称了。
    若有多个形参,则在相应形参前面进行@RequestParam注解。

绑定pojo(简单java对象)

在实际开发中如果参数太多就不能使用@RequestParam去一个一个的映射了,
需要定义一个实体参数对象(POJO)来映射请求参数。Spring MVC 会按请求
参数名和 POJO 属性名进行自动匹配(默认情况下名称必须相同)

自动为该对象填充属性值。
比如说pojo有“name”,则form表单对应需要提交的参数名称也要是“name”,
才能正确映射

自定义参数绑定

当request请求的数据类型格式与pojo中的格式不一致时,需要进行自定义参数绑定
比如:pojo中日期类型为java.util.Date类型,而request中传入的日期格式是yyyy-MM-dd HH:mm:ss
这样会出现格式错误。相当于将一个日期字符串转换为日期类型
转换方式如下:

在springmvc.xml中配置日期转换器

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 这里的conversion-service表示转换器,在下边使用bean配置转换器 -->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

<!-- 自定义参数绑定 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<!-- 日期类型转换器 -->
<bean class="controller.converter.DateConverter"/>
</list>
</property>
</bean>

根据配置,我们要在controller/converter包下编写DateConverter日期转换器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package controller.converter;

import org.springframework.core.convert.converter.Converter;

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateConverter implements Converter<String,Date>{
@Override
public Date convert(String source){
// 转换 "yyyy-MM-dd HH:mm:ss"为Date格式
try{
//参数绑定成功则返回转换后的日期
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(source);
}catch(Exception e){
e.printStackTrace();
}
//否则返回空
return null;
}
}

springmvc和status2的区别

  • springmvc是基于方法开发的,Struts2是基于类开发的
    1.springmvc通过方法的形参来接收数据,方法执行结束后会销毁数据
    2.Struts2通过类的成员变量来接收参数
     (多线程访问时,由于成员变量共享,无法使用单例模式)
    
  • springmvc的controller默认是单例模式,而Struts2是多例模式开发

    单例模式:成员变量是共享的,即在一个请求中修改了这个成员变量,
              其他请求也能读到修改的成员变量的内容(所有请求都用一个对象处理)
    多例模式:每个请求都用一个新的对象处理
    
    springmvc中,在@Controller之前增加@Scope(“prototype”),就可以改变单例模式为多例模式
    

    总的来说,springmvc推荐使用单例模式,两者没有多大的优劣之分

使用ssm时所遇到的一些问题

post乱码问题

表单通过post方式提交,可能会出现乱码问题
解决方法是在web.xml文件中配置一个post乱码过滤器,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 表单通过post方式提交,可能会出现乱码问题,需要设置过滤器解决 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 设置过滤器中的属性,将编码格式统一为utf-8 -->
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<!-- 这里的/* 表示过滤所有请求 -->
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

出现400请求错误的原因

  • 表单提交的数据类型是String类型的,而对应的pojo类中存在不能自动转换的
    数据类型(如:Date类型)。解决方法参考上面ssm知识点所写的自定义参数绑定

  • 后台编写的方法参数顺序不正确(这个暂时还没遇到过)