前言
主要用来记录学习ssm框架中所遇到的一些知识点和遇到的问题(不定时更新)
若对其中一些代码举例不太清楚的,可以参考ssm简单使用
ssm知识点
ssm框架对应的Java开发三层架构
@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
3public 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
21package 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知识点所写的自定义参数绑定后台编写的方法参数顺序不正确(这个暂时还没遇到过)