springMVC简介
是MVC框架,和Spring无缝连接。
第1讲:环境搭建
环境搭建都是从web.xml开始。
核心控制器DispacherServlet
说明:web.xml文件中,配置一个核心的servlet
1.在这之前要先拷贝jar包spring-framework-3.2.0.RELEASE,每一个特定jar包有三个(jar,文档,源码),真正的mvc包是spring-webmvc包。
springMVC
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath*:config/spring-servlet.xml
1
springMVC
/
框架有配置文件,springmvc框架就是springMVC-servlet.xml
springMVC-servlet.xml配置文件默认要放web-inf目录下。代码如下:
import org.springframework.web.servlet.mvc.Controller;
public class HelloWorldController implements Controller{
public ModelAndView handleRequest(HttpServletRequest req,
HttpServletResponse res)throws Exception{
return new ModelAndView("/welcome");
}
}
再建立一个welcome.jsp在根目录就可以做测试了。
启动报错,1.有可能是缺乏commons-logging.jar,
2.配置文件的名字错了,应为springMVC-servlet.xml
可以发请求测试了。localhost:8080/springMVC1/test1/helloworld
例子2:
public class HelloWorldController implements Controller{
public ModelAndView handleRequest(HttpServletRequest req,
HttpServletResponse res)throws Exception{
String hello = "1sh hello提高班";
return new ModelAndView("/welcome","result",hello);
}
}
页面是:${result}
例子3:
public class HelloWorldController implements Controller{
public ModelAndView handleRequest(HttpServletRequest req,HttpServletResponse res)throws Exception{
Map map = new HashMap<>();
map.put("map1","提高班1");
map.put("map2","提高班2");
return new ModelAndView("/welcome","map",map);
}
}要引入jstl的jar包和standard.jar包
页面是:
${m.key} --> ${m.value}
例子4:一个Controller多个方法
public class MultiController extends MultiActionController{
public ModelAndView add(HttpServletRequest req,HttpServletResponse res){
return new ModelAndView("/multi","method","add");
}
public ModelAndView update(HttpServletRequest req,HttpServletResponse res){
return new ModelAndView("/multi","method","update");
}
}
要在spring-servlet.xml文件里配置:
引用刚才写的
可以发请求测试了。
localhost:8080/springMVC2/test1/multi?action=add
localhost:8080/springMVC2/test1/multi?action=update
如果报错,可能是方法少了HttpServletRequest req,HttpServletResponse res
---------------------------------------------------------------------
图片的访问
1.在根目录建文件夹img,并把图片拷贝到这里。
2.jsp页面上:
例子5:
public class MultiController extends MultiActionController{
public ModelAndView img(HttpServletRequest req,HttpServletResponse res){
return new ModelAndView("/staticFile");
}
}
配置bean及配置静态资源访问(不拦截)
引用刚才写的方法解析器
---------------------------------------------------------------------
使用注解方式的配置
springAnnotation-servlet.xml文件:
@Controller
public class UserController{
@RequestMapping(value="/user/addUser",method=RequestMethod.GET)
public ModelAndView addUser(){
String result = "this is addUser----";
return new ModelAndView("/annotation","result",result);
}
@RequestMapping(value="/user/delUser",method=RequestMethod.GET)
public ModelAndView delUser(){
String result = "this is delUser----";
return new ModelAndView("/annotation","result",result);
}
}
说明:按照上面的写法,请求 项目名/user/addUser会跳到annotation.jsp页面。
对于method=RequestMethod.GET或者POST,比较是严格的,不对应的请求是不会有效果的。
---------------------------------------------------------------------
注解的优化
1.开启注解可以用代替
2.当各个方法的请求url开头部分都相同的时候,可以合并在类上加注解。
类上RequestMapping(value="/user2"),方法就可以写RequestMapping(value="/addUser"),
相当 @RequestMapping(value="/user/addUser")
3.想把数据传递到页面可以用request.setAttribute("result",result);[要在方法的参数列表上加HttpServletRequest request]
4.get或者post方式不区分,可把 method=RequestMethod.GET 删掉
5.控制器返回值可以用字符串:return "/jquery";
前方式是:return new ModelAndView("/jquery","result",result);(返回页面及传参)
---------------------------------------------------------------------
参数传递
function addUser(){
var form = document.forms[0];//注意这里是forms
form.action="/springMVC6/user/data/addUser";
form.method="get";
form.submit();
}
姓名:
年龄:
@Controller
@RequestMapping("/user/data")
public class DataController {
@RequestMapping("/addUser")
public String addUser(String userName,String age,HttpServletRequest request){
request.setAttribute("userName",userName);
request.setAttribute("age",age);
return "/userManager";
}
}
说明:参数跟表单的name属性对应,就能接收到。
显示页面:
姓名是:${userName}
年龄是:${age}
说明:乱码是常见的。解决方法:server.xml里在这行加上URIEncoding="UTF-8"
---------------第9讲---------------
$(function(){
$("#add").click(function(){
var userName = $("#userName").attr("value");
var age = $("#age").attr("value");
var user = {userName:userName,age:age};
$.ajax({
url:"/springMVC6/user/data/addUserJson",
type:"get",
data:encodeURI(user),
success:function(data){
alert("userName-->"+data.userName);
},
});
});
});
@RequestMapping("/addUserJson")
public String addUserJson(User user,HttpServletRequest request){
request.setAttribute("userName",user.getUserName());
request.setAttribute("age",user.getAge());
return "/userManager";
}
图片路径的注意点:
当类的路径配置是"/user/data"时,图片路径是../xxx的话,上一级目录就是user,不会返回到项目的根目录,
所以js引入路径最好是写src="/项目名/js/xxx"
---------------第10讲---------------
@RequestMapping("/addUserJson")
public String addUserJson(User user,HttpServletRequest request){
String result = "{\"userName\":\""+user.getUserName()+"\",\"age\":\""+user.getAge()+"\"}";
PrintWriter = null;
response.setContentType=("application/json");
try{
out = response.getWriter();
out.write(result);
}catch(IOException e){
e.printStackTrace();
}
}
拿json数据后台要out.write(),前台用jQuery的success回调函数就能拿结果function(data){}
---------------第11讲---------------
上传文件解析器配置
选择文件:
说明:上传enctype属性必须为multipart/form-data
少了两个上传文件的jar包,要拷贝。
另外文件上传
必须采用method="post"方式---------------第12讲:上传文件---------------
说的那个接口的方法用name属性的值
@RequestMapping("/upload2")
public void upload2(HttpServletRequest request,HttpServletResponse response){
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
if(multipartResolver.isMultipart(request)){
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)(request);
Iterator iter = multiRequest.getFileNames();
while(iter.hasNext()){
MultipartFile file = multiRequest.getFile((String)iter.next());
if(file != null){
String fileName = "demoUpload" + file.getOriginalFilename();
String path = "D:/" + fileName;
File localFile = new File(path);
file.transferTo(localFile);
file.getInputStream();
}
}
}
}
尽量不用springmvc配置上传大小,在客户端验证,减少服务器压力。
---------------第13讲:与spring集成---------------
struts2和spring集成关键点:
1.struts.xml文件中,标签里,
说明:如果不用spring管理bean,要写包名+类名,有spring后写bean的id即可。
2.
没有声音
---------------第14讲:与spring集成2---------------
@Controller
public class SpringController{
@Resource(name="springManager")
private ISpring springManager;
@RequestMapping("/spring/get")
public String get(){
springManager.get();
return "/success";
}
}
---------------第15讲:与spring上下文关系---------------
//spring的上下文
WebApplicationContext ac1 = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
//springMVC的上下文
WebApplicationContext ac2 = RequestContextUtils.getWebApplicationContext(request);
ISpring springManager = (ISpring)ac1.getBean("springManager");
在一个配置文件里写bean很臃肿,spring可以导入配置文件。
---------------第16讲:与hibernate简单实例---------------
- hibernate五大对象
Configuration
sessionFactory
Session
Transaction
Query和criteria
classpath*:com/tgb/.../hibernate.cfg.xml
hibernate.cfg.xml里是这样:
public class User{
@Id
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid",strategy="uuid")
private String id;
}
---------------第18讲:与hibernate简单实例---------------
需配置事务bean:
说明:事务管理哪个sessionFactory,可在里面指定
配置事务特性描述(策略):
PROPAGATION_REQUIRED,-Exception
PROPAGATION_REQUIRED,-Exception
PROPAGATION_REQUIRED,-Exception
PROPAGATION_REQUIRED,-Exception
PROPAGATION_REQUIRED,-Exception
PROPAGATION_NEVER
---------------第19讲:整合简单实践---------------
public interface IUserDAO{
public void addUser(User user);
}
public class UserDAO implements IUserDAO{
public void addUser(User user){
}
}
另一教程
---------------------------------------------------------------------
核心原理
- 用户发送请求给服务器。
- 服务器接收到请求。发现DispacherServlet可以处理,于是调用DispacherServlet。
- DispacherServlet内部,通过HandleMapping用于检查一个url有没有对应的控制器。如果有,则调用,没则报404.
- 控制器开始执行。
- 控制器执行完毕后,如果返回字符串,则ViewResolver将字符串转化成相应的视图对象;
如果返回ModelAndView对象,该对象本身就包含了视图对象信息。
即改成return new ModelAndView("index");
- DispacherServlet将执行视图对象中的数据,输出给服务器。
- 服务器将数据输出给客户端。
注意:ModelAndView是web.servlet.ModelAndView包的
HandlerMapping
BeanNameUrlHandlerMapping
ModelAndView
-- 常用注解
- @Controller
在类上面加 @Component和 @Controller是等价的,表明是控制器。
- @RequestMapping
形式一:在类前面定义,则将url和类绑定。具体调哪个方法呢?需要url里边携带一个参数,如:
@RequestMapping(params="method=reg")
形式二:在方法前面定义,则将url和类的方法绑定。
- @RequestParam
比如有这样的一种情况,提交的表单的,
但是控制器的方法是public String reg3(String name){},
用于加在方法参数的前面,当提交的参数的name属性值跟参数不一致时,就可以加。
public String reg3( @RequestParam("uname") String name){//提交表单的name属性值是uname
....
}
说明:加 @RequestParam("uname")的意思就是把表单的属性值为uname所提交的数值赋值给name这个参数。
- @SessionAttributes({"u","a"})
说明:在某方法里如果想使用ModelMap,在方法的参数列表里加: ,ModelMap map 就可以(会自动注入);
如果想使用HttpServletRequest req,在方法的参数列表里加: ,HttpServletRequest req
从而req.getSession().setAttribute("x","xxx");
map.put("a","aaa");-->页面上${RequestScope.a}
在类上加了这个注解后,key为u和a也会在session里存一份。
- @ModelAttribute
这个注解可以跟 @SessionAttributes配合在一起用。可以将ModelMap中属性的值通过该注解自动赋给指定变量。
public String reg5( @ModelAttribute("u") String uname,ModelMap map){}
说明:这里有个uname参数,uname我不需要表单给我参数,我直接把ModelMap里的属性key为u的值直接给我赋过来。
请求转发与重定向
转发 return "forward:user.do?method=reg";不写也是转发
重定向 return "redirect:http://www.baidu.com";
modelAndView.setViewName("index");
User u = new User("jack");
modelAndView.addObject("uu",u);//较好用
return modelAndView;
页面上${requestScope.uu.uname}
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
value="org.springframework.web.servlet.view.JstlView" />
/IMPM/WebContent/modules/saleManagement/earlyWarningManagement/earlyWarningManageDetail.jsp
-----------------------------------------------------------------
要让? @Autowired?起作用必须事先在?Spring?容器中声明AutowiredAnnotationBeanPostProcessor?Bean
?
当不能确定Spring容器中一定拥有某个类的bean时,可以用 @Autowired(required?=?false),这等于告诉?Spring:在找不到匹配?Bean?时也不报错
我们在?Spring?容器中配置了两个类型为?Office?类型的?Bean,当对?Boss?的?office?成员变量进行自动注入时,Spring?容器将无法确定到底要用哪一个?Bean,因此异常发生了。?Spring?允许我们通过?@Qualifier?注释指定注入?Bean?的名称,这样歧义就消除
了
@Resource作用相当于 @Autowired, @Resource默认按byName自动注入。如果使用name属性,则使用byName的自动注入策略;而使用type属性时则使用byType自动注入策略。
要让JSR-250的注释生效,除了加这些注释外,还需要在Spring容器中注册一个负责处理这些注释的BeanPostProcessor:
标注了 @PostConstruct的方法将在类实例化后调用,而标注了 @PreDestroy的方法将在类销毁之前调用。
@Component 注解的类就相当于xml配置文件里定义的bean。默认情况下通过 @Component定义的Bean都是singleton的,如果需要使用其它作用范围的Bean,可通过 @Scope 来达到目标。
==================第二套====================
- mvc在b/s系统下的应用,c控制器,m模型(pojo,action,service,dao),v视图
mvc是一个设计模式.
处理器映射器是干嘛的,是根据url找到对应的处理器。
处理器适配器去执行Handler。
第一步:发起请求到前端控制器DispatcherServlet
第二步:前端控制器查找Handler(可根据xml配置、注解进行查找)
第三步:处理器映射器HandlerMapping向前端控制器返回Handler(其实返回一个执行链)
第四步:前端控制器调用处理器适配器去执行Handler
第五步:处理器适配器去执行Handler
第六步:Handler执行完成,给适配器返回ModelAndView
第七步:处理器适配器向前端控制器返回ModelAndView(框架底层对象)
第八步:前端控制器请求视图解析器去进行视图解析。
第九步:视图解析器向前端控制器返回view
第十步:前端控制器进行视图渲染(将模型数据填充到request域中)
第十一步:前端控制器向用户响应结果
组件:
1.前端控制器DispatcherServlet
作用:接收请求,响应结果,相当于转发器。
2.处理器映射器
作用:根据请求的url查找Handler。
3.处理器适配器
作用:按照特定的规则去执行Handler
注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler。
4.视图解析器View resolver
作用:进行视图解析,根据逻辑视图名解析成真正的view
5.视图view
view是一个接口,实现类支持不同的view类型(jsp,freemarker,pdf...)
- 配置前端控制器(web.xml文件)
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
springmvc
*.action
接下来要在springmvc.xml里配置 1.处理器映射器 2.处理器适配器 3.视图解析器
注意:多个映射器可以并存,前端控制器判断url能让哪些映射器映射,就让正确的映射器处理。
这时java代码是:
public class ItemsController implements Controller
request.setAttribute("itemsList",itemsList);
//视图
request.getRequestDispatcher("/WEB-INF/jsp/items/itemsList.jsp").forward(request,response);
好处是可以响应json数据
===================分隔线===================
ItemsController1
ItemsController1
注意点3.多个映射器可以并存,前端控制器判断url能让哪些映射器映射,就让正确的映射器处理。
非注解的处理器适配器
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
要求编写的Handler实现Controller接口
org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter
要求编写的Handler实现HttpRequestHandler接口。
映射器
在spring3.1之前使用org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping注解映射器。
在spring3.1之后使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping注解映射器。
适配器
在spring3.1之前使用org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter注解适配器。
在spring3.1之后使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter注解适配器。
public class ItemController implements Controller{
public ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception{
//调用service
List itemsList = new ArrayList();
//填充静态数据,模拟数据库
Items items_1 = new Items();
items_1.setName("");
ModelAndView modelAndView = new ModelAndView();
//相当于request的setAttribute,在jsp页面可取数据
modelAndView.addObject("itemsList",itemsList);
//指定视图
modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
return modelAndView;
}
}
小结:
重点掌握注解的方式。
对标记有@Controller的类中标记有@RequestMapping的方法进行映射。
视图解析器
表现层 |
业务层 |-- spring将各层进行整合、事务控制。
持久层 |
第一步:整合dao层。
使用mapper的扫描器自动扫描mapper接口,在spring中进行注册。
第二步:整合service层。
将service接口配置在spring配置文件中。
第三步:
所需要的jar包:
数据库驱动
log4j包
数据库连接池包
jstl包
spring
items.name LIKE '%${itemsCustom.name}%'
SELECT items.* FROM items
/**商品包装对象*/
public class ItemsQueryVo{
private Items items;//商品信息
private ItemsCustom itemsCustom;
}
/**商品信息的扩展*/
public class ItemsCustom extends Items {
//添加扩展属性
}
public class Items{
这里是自动生成的
}
接口
public interface ItemsMapperCustom{
public List findItemsList(ItemsQueryVo itemsQueryVo)throws Exception;
}
21小节:
url映射
窄化请求路径
限制请求,配置的是允许的类型。
24小节:
参数绑定默认支持的类型
HttpServletRequest
HttpServletResponse
HttpSession
Model/ModelMap model是接口,ModelMap是一个接口实现
简单类型 Integer
pojo
自定义转换器
跟struts2区别:
1.springmvc将url和controller方法映射,映射成功后springmvc生成一个Handler对象,对象中只包括了一个method,方法执行结束,形参数据销毁。
2.springmvc可以进行单例开发,并建议使用单例开发,struts2通过类的成员变量接收参数,无法使用单例,只能使用多例。
3.struts2速度慢,在于使用struts标签,建议使用jstl
springmvc第二天
复习
DispatcherServlet 前端控制器:接收request,进行response
接收到请求之后,需要调用一个组件HandlerMapping处理器映射器:根据url查找Handler。(xml配置或者注解)
HandlerAdapter处理器适配器:根据特定规则去执行Handler,编写Handler时需要按照HandlerAdapter的要求去编写。
Handler处理器(后端控制器):需要程序员去编写,常用注解开发方式。
Handler处理器执行后结果 是ModelAndView(Adapter处理决定的),具体开发时Handler返回方法值类型包括:ModelAndView、
String(逻辑视图名)、void(通过在Handler形参中添加request和response,类似servlet开发,可实现json数据输出)
View resolver视图解析器:根据逻辑视图名生成真正的视图
View视图:jsp页面,仅是数据展示,没有业务逻辑。
自定义参数绑定
定义的Converter接口
注意:要转换的目标类型一定和接收的pojo中的属性类型一致。
将定义的Converter实现类注入到处理器适配器中。
学习内容
绑定List
进入批量修改页面,批量修改的提交
使用List接收页面提交的批量数据,要通过包装类定义List属性。
绑定Map:同样通过包装类,页面也是定义属性名,info['name']
- validation校验
@Size(min=1,max=30,message="{items.name.length.error}",groups={ValidGroup1.class}) 校验组1
private String name;
@NotNull(message="{items.createtime.isNull}") 非空校验
private Date createtime;
ValidationMessages.properties文件:
items.name.length.error=请输入1到30个字符
items.createtime.isNull=请输入生成日期
public String editItemsSubmit(Model model,@Validated(value={ValidGroup1.class}) ItemsCustom itemsCustom,BindingResult bindingResult)throws Exception{
if(bindingResult.hasErrors()){
//输出错误信息
List allErrors = bindingResult.getAllErrors();
for(ObjectError objectError:allErrors){
System.out.println(objectError.getDefaultMessage());
}
model.addAttribute("allErrors",allErrors);
}
}
页面上:
${error.defaultMessage}
- 分组校验
校验分组接口
public interface ValidGroup1{
}
public interface ValidGroup2{
}
- 数据回显
@ModelAttribute("items") 可以指定pojo回显到页面在request中的key
- JSON交互
1.要求请求的是json串,所以在前端页面中需要将请求内容转成json,不方便。
2.请求key/value,输出json,常用。