配色: 字号:
springMVC入门教程
2015-09-07 | 阅:  转:  |  分享 
  
目录

SpringMvc教程 1

初识springMVC 1

背景 1

常见MVC框架比较 1

基于spring3.2的采用annotation方式搭建springMVC环境 1

springMVC的RequestMapping的基本设置 6

在controller中获取前台传递的参数 8

在controller中获取web元素 9

将controller中数据传递到jsp页面 10

设置跳转方式为重定向或者转发 14

视图解析器的配置和使用 14

controller中方法的返回值类型 15

springMVC的文件上传于下载 18

springMVC和jQuery的Ajax结合 22





SpringMvc教程

作者:DK

初识springMVC

背景

Spring框架提供了构建Web?应用程序的全功能MVC模块。使用Spring可插入的MVC架构,可以选择是使用内置的SpringWeb框架还是Struts这样的Web框架。通过策略接口,Spring框架是高度可配置的,而且包含多种视图技术,例如JavaServerPages(JSP)技术、Velocity、Tiles、iText和POI。SpringMVC框架并不知道使用的视图,所以不会强迫您只使用JSP技术。SpringMVC分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。



运行性能上:

Jsp+servlet>struts1>springmvc>struts2+freemarker>>struts2,ognl,值栈。

开发效率上,基本正好相反。值得强调的是,springmvc开发效率和struts2不相上下。

Struts2的性能低的原因是因为OGNL和值栈造成的。所以,如果你的系统并发量高,可以使用freemaker进行显示,而不是采用OGNL和值栈。这样,在性能上会有相当大得提高。



基于spring3.2的采用annotation方式搭建springMVC环境

上官网下载对应的zip包当然该zip并非最新的。下载地址为:http://repo.spring.io/webapp/home.html?0

解压之后得到目录:打开libs会看到会多jar这里边包括了所有的jar和source和doc。当然我们只是需要使用jar就可以了。



3、创建空的web项目目录结构如下:其中user实体类为:



publicclassUser{

privateStringname;

privateIntegerage;

privateDatebirth;



publicStringgetName(){

returnname;

}



publicvoidsetName(Stringname){

this.name=name;

}



publicUser(Stringname,Integerage,Datebirth){

super();

this.name=name;

this.age=age;

this.birth=birth;

}



publicIntegergetAge(){

returnage;

}



publicvoidsetAge(Integerage){

this.age=age;

}



publicDategetBirth(){

returnbirth;

}



publicvoidsetBirth(Datebirth){

this.birth=birth;

}



publicUser(){

super();

//TODOAuto-generatedconstructorstub

}



publicUser(Stringname){

super();

this.name=name;

}



@Override

publicStringtoString(){

//TODOAuto-generatedmethodstub

return"["+name+"]";

}

}

4、在项目中添加如下jar文件:spring-webmvc-3.2.0.RELEASE.jar

spring-core-3.2.0.RELEASE.jarspring-context-3.2.0.RELEASE.jarspring-beans-3.2.0.RELEASE.jarspring-web-3.2.0.RELEASE.jarcommons-logging.jarspring-expression-3.2.0.RELEASE.jar

其中commons-logging.jar请单独下载。

5、在web.xml中添加过滤器的配置。

example

org.springframework.web.servlet.DispatcherServlet



contextConfigLocation

/WEB-INF/spring-servlet.xml



1





example

.do

这个org.springframework.web.servlet.DispatcherServle即为springMVC的核心控制器。

其中init-param中配置的是spring的配置文件的文件路径。

6、在WEB-INF下添加spring的配置文件spring-servlet.xml文件内容如下:


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:p="http://www.springframework.org/schema/p"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:util="http://www.springframework.org/schema/util"

xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsd

http://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd

http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-3.0.xsd">

















其中schemaLocation和xmlns建议直接拷贝。7、创建UserController如下:@Controller

@RequestMapping("/user.do")

publicclassUserController{



@RequestMapping(params="method=add")

publicStringaddUser(Modelmodel){

model.addAttribute("message","添加了一个用户");

System.out.println("UserController.addUser()");

return"/WEB-INF/jsp/addsuc.jsp";

}

}其中@RequestMapping("/user.do")的配置是指:该controller的请求url为:user.do

@RequestMapping(params="method=add")的注解是指:凡是请求的url为:user.do而带了参数method=add的请求会由方法addUser来处理。

addUser的形参model为后续讲解内容。

return"/WEB-INF/jsp/addsuc.jsp";是告诉spring完成处理之后直接进入该视图。

8、添加对应的页面,测试请求user.do?method=add



springMVC的RequestMapping的基本设置

在类的上面注解RequestMapping("/ex.do")意思为所有的ex.do请求全部进入该类处理。"/user.do").所有的user.do请求都会进入该Controller。

2、在自定义的controller中会调用有@RequestMapping注解字样的方法来处理请求。@Controller

@RequestMapping("/user.do")

publicclassUserController{



@RequestMapping

publicStringaddUser(Modelmodel){

model.addAttribute("message","添加了一个用户");

System.out.println("UserController.addUser()");

return"/WEB-INF/jsp/addsuc.jsp";

}

}3、当然可以编写多个处理请求的方法,而这些方法的调用都是通过@RequestMapping的属性类控制调用的。@RequestMapping属性:

value:指定请求的实际地址,指定的地址可以是URITemplate模式(最终请求的url为类的注解的url+方法注解的url)

value的uri值为以下三类:

A)可以指定为普通的具体值;



@Controller

@RequestMapping("/user")

publicclassUserController{

@RequestMapping(value="/some.do")

publicModelAndViewhandleRequest(HttpServletRequestarg0,

HttpServletResponsearg1)throwsException{

System.out.println("handleRequest");

returnnewModelAndView("/WEB-INF/jsp/addsuc.jsp");

}

}

该注解的是说:请求的url为”user/some.do”就会进入该方法(handleRequest)处理。

url:user/some.do

B)可以指定为含有某变量的一类值(URITemplatePatternswithPathVariables);

@RequestMapping(value="/{userId}/delete.do",method=RequestMethod.GET)

publicStringdelete(@PathVariableStringuserId){

System.out.println("delete:"+userId);

return"/WEB-INF/jsp/addsuc.jsp";

}

这个注解:url中带了参数的数据userIdurl:user/1123/delete.do

使用@PathVariable指定形参接收url中的数据

C)可以指定为含正则表达式的一类值(URITemplatePatternswithRegularExpressions);



@RequestMapping(value="/{userBirth:\\d{4}-\\d{2}-\\d{2}}/update.do")

publicStringupdate(@PathVariableStringuserBirth){

System.out.println("userBirth:"+userBirth);

return"/WEB-INF/jsp/addsuc.jsp";

}

请求的url类似:user/1990-11-11/update.do

使用@PathVariable指定形参接收url中的数据

method:指定请求的method类型,GET、POST、PUT、DELETE等;(也就是说只有制定类型的请求才会进入该方法处理)

consumes:指定处理请求的提交内容类型(Content-Type),例如application/json,text/html;

produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;

params:指定request中必须包含某些参数值是,才让该方法处理。

headers:指定request中必须包含某些指定的header值,才能让该方法处理请求。

4、当类没有@RequestMapping注解时,则直接参考方法的注解匹配对于的url。

@Controller

publicclassUserController{

@Controller

@RequestMapping("/user.do")

publicvoidmanagerUser(){}

}

在这里url为user.do则直接使用managerUser处理请求。



在controller中获取前台传递的参数

将页面数据传递到controller





用户名:


年龄:


生日:






C

/

1、直接使用形参获取前台传递的参数数据

要注意的是形参的名字必须和页面参数的名字

@parammodel

@paramname

@paramage

@parambirth

@return

/

@RequestMapping(method=RequestMethod.POST)

publicStringaddUser(Modelmodel,Stringname,Integerage,Datebirth){

model.addAttribute("message","添加了一个用户");

System.out.println("name:"+name+"\tage:"+age+"\tbirht:"+birth);

System.out.println("UserController.addUser()");

return"/WEB-INF/jsp/addsuc.jsp";

}



/

2、使用对象接受前台传递的参数,

要注意的是前台传递的参数的名称必须和对象的属性名称一直,如果不一致则可以使用@ModelAttribute("u")Stringuname指定

/

@RequestMapping(method=RequestMethod.POST)

publicStringaddUser(Modelmodel,Useruser){

model.addAttribute("message","添加了一个用户");

System.out.println("name:"+user.getName()+"\tage:"+user.getAge()+"\tbirht:"+user.getBirth());

System.out.println("UserController.addUser()");

return"/WEB-INF/jsp/addsuc.jsp";

}





在controller中获取web元素

当某个方法需要使用web对象时(request,response,session,application)

可以使用如下方式:

除过application其他的对象都可以直接设为方法的形参即可。spring会自动将对应的对象传递给对应的形参。

而application对象可以使用session对象获取。



当然也可以在方法中使用response对象重定向到其他的url这时方法最后return的url则可以视作无效。

同样的也可以使用request对象转发到其他的url。



@RequestMapping(value="/web.do")

publicStringgetWebElement(HttpServletRequestrequest,HttpServletResponseresponse,HttpSessionsession)throwsIOException,ServletException{

System.out.println("使用request获取的前台参数:"+request.getParameter("pname"));

request.setAttribute("message","这个是request中的数据");

session.setAttribute("message","这个是session中的数据");

session.getServletContext().setAttribute("message","这个是application中的数据");

//response.sendRedirect("http://www.baidu.com");

//returnnull;



//request.getRequestDispatcher("/WEB-INF/jsp/showData.jsp").forward(request,response);



return"/WEB-INF/jsp/showData.jsp";

}







将controller中数据传递到jsp页面

1、可以在controller中获取request对象,然后将数据设置为request对象的属性,然后使用转发的方式进入jsp即可。

2、将方法的返回值该为ModelAndView在返回时,将数据存储在ModelAndView对象中如:

newModelAndView("/WEB-INF/jsp/showData.jsp","message",message)

其中第一个参数为url,第二个参数为要传递的数据的key,第三个参数为数据对象。

在这里要注意的是数据是默认被存放在request中的。



//使用modelAndView对象将数据传递到前台。

@RequestMapping(value="/mad/showData_1.do")

publicModelAndViewshowData_1(){

Stringmessage="这个是要传递的数据";

//其中第一个参数为url,第二个参数为要传递的数据的key,第三个参数为数据对象。

//在这里要注意的是数据是默认被存放在request中的。

returnnewModelAndView("/WEB-INF/jsp/showData.jsp","message",message);

}

前台页面获取方式:

request:${requestScope.message}


2.1、可以在类的前面添加注解@SessionAttributes({"message","user"})

这个注解可以设置对应的model中参数也会在session中存储一份。该注解中的参数为一个集合,可以写多个,如上面的例子,其中message和user都是存储的数据的key.



@SessionAttributes({"message","user"})//modelAndView中的对应的数据也会在session中存储一份



session:${sessionScope.message}




3、数据modelAndView返回一个集合

该处理方式和上面的处理方式一直,因为modelAndView接受的数据类型是Object的,集合也是一样的处理方式

//使用modelAndView对象将数据传递到前台。

//传递多个参数(不同类型的)

@RequestMapping(value="/mad/showData_2.do")

publicModelAndViewshowData_2(){

System.out.println("showData_2");

Stringmessage="这个是要传递的数据";

Useruser=newUser("张三",12,newDate());

Listus=newArrayList();

us.add(newUser("张三",12,newDate()));

us.add(newUser("张四",13,newDate()));

us.add(newUser("张五",14,newDate()));

ModelAndViewmad=newModelAndView("/WEB-INF/jsp/showData.jsp");

//将数据存入modelMap

mad.addObject("message",message);

mad.addObject(user);//默认为类名的首字母小写

mad.addObject("users",us);

returnmad;

}



request:${requestScope.message}




${u.name}-${u.age}-${u.birth}






4、使用modelAndView传递多个参数。

可以通过ModelAndView的mad.addObject("message",message);方法设置参数。

该方法中第一个参数为数据的key,第二个参数为数据对象。

也可以使用mad.addObject(user);方法

该方法中数据的参数为数据对象,数据的key为该对象的类的类名(其中首字母小写)。

5、使用ModelMap传递多个数据到jsp中。

在方法的参数列表中添加形参ModelMapmap,spring会自动创建ModelMap对象。

然后调用map的put(key,value)或者addAttribute(key,value)将数据放入map中,spring会自动将数据存入request。



//使用modelMap对象将数据传递到前台。

//传递多个参数(不同类型的)

@RequestMapping(value="/mad/showData_3.do")

publicStringshowData_3(ModelMapmap){

System.out.println("showData_3");

Stringmessage="这个是要传递的数据";

Useruser=newUser("张三",12,newDate());

Listus=newArrayList();

us.add(newUser("张三",12,newDate()));

us.add(newUser("张四",13,newDate()));

us.add(newUser("张五",14,newDate()));

//将数据存入modelMap

map.put("message",message);

map.addAttribute("user",user);

map.put("users",us);

return"/WEB-INF/jsp/showData.jsp";

}

页面调用:

request:${requestScope.message}


session:${sessionScope.message}


application:${applicationScope.message}





ModelMap中的数据



${requestScope.message}


${requestScope.user.name}


列表





${u.name}-${u.age}-${u.birth}




设置跳转方式为重定向或者转发

1、spring默认的跳转方式即为转发,当然转发也可以写作:return"forward:/WEB-INF/jsp/showData.jsp";

2、重定向必须写作:return"redirect:http://www.baidu.com";



视图解析器的配置和使用

1、在spring-servlet.xml中配置视图解析器











配置该解析器之后,那么controller中的返回的视图url就可以改写了。



return"showData";实际跳转的url为:/WEB-INF/jsp/showData.jsp





controller中方法的返回值类型

springMvc中controller中方法的返回值除了可以返回String和ModelAndView两种类型外还有其他类型。

在这里上面用过的两种类型不再赘述。

其他类型还包括:void、ModelMap、Map、Object、map、List、Set。一般建议使用String。

1、void返回值类型为void则只是纯粹的执行了方法中的程序,然后响应的url依然为请求的url

例如案例中请求为index.do则响应的url为index在视图解析器解析之后得到的最终的url为/WEB-INF/jsp/index.jsp



//返回值为vood

@RequestMapping(value="/index.do",params="type=void")

publicvoidresultVoid(HttpServletRequestrequest){

request.setAttribute("void","resultVoid");

}

2、ModelMap返回值为modelMap时,响应的url和void一致。

只是存储在MpdelMap中的数据可以在jsp页面中取出。



//返回值为ModelMap

@RequestMapping(value="index.do",params="type=modelMap")

publicModelMapresultModelMap(ModelMapmap){

map.put("msg","这里是modleMap中的数据");

returnmap;

}

3、Map和modelMap几乎完全一直。



//返回值为Map

@RequestMapping(value="index.do",params="type=map")

publicMapresultMap(){

Mapmap=newHashMap();

map.put("msg","这里是Map中的数据");

returnmap;

}

4、List返回list是响应的url和void一致。

只是spring会将list对象存储在request中,而该对象的存储的key为:当list中存储为String类型数据时key为:stringList,当存储为User对象时key为:userList。其他的类型的可以类比。//返回值为List

@RequestMapping(value="index.do",params="type=list_string")

publicListresultList_String(){

Listls=newArrayList();

ls.add("list1");ls.add("list2");ls.add("list3");

returnls;

}//返回值为List

@RequestMapping(value="index.do",params="type=list_user")

publicListresultList_User(){

Listls=newArrayList();

ls.add(newUser("张三"));

ls.add(newUser("张四"));

returnls;

}

5、Set返回Set类型的数据时和List除了没有顺序之外,其他都一直。//返回值为Set

@RequestMapping(value="index.do",params="type=set_user")

publicSetresultSet_User(){

Setls=newHashSet();

ls.add(newUser("张三"));

ls.add(newUser("张四"));

returnls;

}

6、Object返回object时,响应的url和以上一直,spirng也会将返回的对象存储在request中,该对象在request中的key为该对象类型的类名(首字母小写)

//返回值为User

@RequestMapping(value="index.do",params="type=user")

publicUserresultUser(){

returnnewUser("张四");

}



返回值类型





Void



无返回值类型


${requestScope.void}





ModelMap



返回ModelMap


${requestScope.msg}





Map



返回map


${requestScope.msg}





List



返回List<String>


${requestScope.stringList}





List



返回List<User>


${requestScope.userList}



Set



返回Set<User>


${requestScope.userSet}





User(Object)



返回User(Object)


${requestScope.user}









springMVC的文件上传于下载

1、springmvc文件的上传也是借助于两个工具所以需要添加两个jar

apache-commons-fileupload.jar

apache-commons-io.jar

2、在spring-servlet.xml中添加文件上传的处理bean的配置。
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">











其中属性

的配置配置的是临时文件目录,spring会将文件先传到临时文件,然后我们再调用对应的API将临时文件写到目标文件。

3、编写上传文件的controller

3.1上传一个文件

直接在处理的方法中设置形参@RequestParam("file")CommonsMultipartFilefile

注意这里的参数必须使用@RequestParam指定。

然后调用方法file.getFileItem().write(targetFile);将临时文件写出到目标文件。



/

上传一个文件

@paramname

@paramfile

@paramsession

@return

/

@RequestMapping(value="/upload.do",method=RequestMethod.POST)

publicStringfileUpLoad(Stringname,@RequestParam("file")CommonsMultipartFilefile,HttpSessionsession){

if(!file.isEmpty()){

Stringpath=session.getServletContext().getRealPath("/upload/");

StringfileName=file.getOriginalFilename();

StringfileType=fileName.substring(fileName.lastIndexOf("."));

FiletargetFile=newFile(path,newDate().getTime()+fileType);

try{

file.getFileItem().write(targetFile);

}catch(Exceptione){

e.printStackTrace();

}

}

return"showData";

}

3.2上传多个文件

上传多个文件时,其实和上传一个文件一样,只是将形参改为@RequestParam("file")CommonsMultipartFile[]file

然后我们只需在方法中循环处理这些文件即可。

示例:

/

上传多个文件

@paramname

@paramfiles

@paramsession

@return

/

@RequestMapping(value="/mupload.do",method=RequestMethod.POST)

publicStringmuFileUpLoad(Stringname,@RequestParam("file")CommonsMultipartFile[]files,HttpSessionsession){

if(files!=null&&files.length>0){

Stringpath=session.getServletContext().getRealPath("/upload/");

for(CommonsMultipartFilefile:files){

StringfileName=file.getOriginalFilename();

StringfileType=fileName.substring(fileName.lastIndexOf("."));

FiletargetFile=newFile(path,newDate().getTime()+fileType);

try{

file.getFileItem().write(targetFile);

}catch(Exceptione){

e.printStackTrace();

}

}



}

return"showData";

}

4、文件下载

文件下载其实和spring没关系,还是使用最普通的方式实现下载即可,在这里不赘述。

示例:

/

文件下载

@paramsession

@paramresponse

@paramfileName

@paramisOnline

@throwsException

/

@RequestMapping(value="/downLoad.do",method=RequestMethod.GET)

publicvoiddownLoad(HttpSessionsession,HttpServletResponseresponse,StringfileName,booleanisOnline)throwsException{

Stringpath=session.getServletContext().getRealPath("/upload/")+"\\"+fileName;

Filefile=newFile(path);

System.out.println(path);

if(!file.exists()){

response.sendError(404,"您要下载的文件没找到");

return;

}

BufferedInputStreambufIn=newBufferedInputStream(newFileInputStream(file));

byte[]buff=newbyte[1024];

intlen=-1;

response.reset();

if(isOnline){

URLu=newURL("file:///"+path);

response.setContentType(u.openConnection().getContentType());

response.setHeader("Content-Disposition","inline;filename="+fileName);



}else{

response.setContentType("application/x-msdownload");

response.setHeader("Content-Disposition","attachment;filename="+fileName);

}

OutputStreamout=response.getOutputStream();

while((len=bufIn.read(buff))!=-1){

out.write(buff,0,len);

out.flush();

}

bufIn.close();

out.close();

}





springMVC和jQuery的Ajax结合

1、使用@RequestBody接收前台传递的json集合数据。

首先:从spring3.1开始只要配置了就不用再配置其他转换器了。

然后添加json的几个jar:jackson-annotations-2.4.0.jar,jackson-core-2.4.1.jar,jackson-databind-2.4.1.jar

这些jar建议从官网上下载最新的(http://wiki.fasterxml.com/JacksonDownload)

在这里要注意的是,如果jackson的jar如果和spring的版本不匹配,可能会出现响应状态码415.如果出现415响应状态吗,不能解决可以联系此文档的主人qq:2780004063或者发送邮件。

@RequestBody将HTTP请求正文转换为适合的HttpMessageConverter对象。

1.1

在前台js中创建JSON字符串。如[{name:''11'',age:12},{name:''222'',age:15}],

然后使用JSON.stringify将该json对象转换为json字符串,因为@RequstBody只接受json字符串。



$("#saveUser").click(function(){

varusers=[{

name:''张三'',

age:18,

birth:''2014-11-11''

},{

name:''王五'',

age:18,

birth:''2014-11-11''

},{

name:''李四'',

age:18,

birth:''2014-11-11''

}];

$.ajax({

type:''POST'',

data:JSON.stringify(users),

contentType:''application/json'',

dataType:''json'',

url:''user/saveJsonUser.do'',

success:function(data){

alert("OK");

},

error:function(e){

alert("error");

}

});

});

1.2

使用Ajax提交数据需要注意的是:contentType:''application/json'',dataType:''json'',

这两个属性必须这样设置。

1.3

Controller中的处理方法的形参需要添加注解@RequestBody而且形参必须是数组或者list。

如:@RequestBodyUser[]users

示例:

/

使用@RequestBody接受前台传递的一组json数据

@paramusers

@return

/

@RequestMapping(value="/saveJsonUser.do",method=RequestMethod.POST)

publicStringsaveJsonUser(@RequestBodyUser[]users){

for(Useruser2:users){

System.out.println(user2);

}

System.out.println(users);

return"saveUser";

}

2、使用@Response返回指定形式的返回值。

在返回值类型钱添加@Response注解之后,spring不会再对返回的url进行解析,而是直接将返回的对象转化成对应的字符串形式放入respons的流中输出到客户端。

2.1如果返回的为字符串,则直接将该字符串输出到客户端。



/

使用@ResponseBody返回普通字符串。

@paramname

@return

/

@RequestMapping(value="/checkName.do")

public@ResponseBodyStringcheckName(Stringname){

name="userNameis:"+name;

returnname;

}

2.2如果是其他形式的对象,则spring会自动将这些对象转换为对应的json形式的字符串,然后将字符串输出到客户端。



/

使用@ResponseBody返回一个对象集合。

@paramname

@return

/

@RequestMapping(value="/getUsers.do")

public@ResponseBodyListgetUsers(){

Listus=newArrayList();

us.add(newUser("张三",12,newDate()));

us.add(newUser("张四",13,newDate()));

us.add(newUser("张五",14,newDate()));

returnus;

}



/

使用@ResponseBody返回一个对象。

@paramname

@return

/

@RequestMapping(value="/getUser.do")

public@ResponseBodyUsergetUser(){

returnnewUser("老黑",45,newDate());

}



还有springMVC和hibern的整合尚未整理,待续。





















献花(0)
+1
(本文系文梅文档首藏)