1
一、导入相关jar包
commons-logging-1.1.1.jar (必须)
jstl.jar
spring-aop-4.3.0.RELEASE.jar (必须)
spring-aspects-4.3.0.RELEASE.jar
spring-beans-4.3.0.RELEASE.jar (必须)
spring-context-4.3.0.RELEASE.jar (必须)
spring-context-support-4.3.0.RELEASE.jar (必须)
spring-core-4.3.0.RELEASE.jar (必须)
spring-expression-4.3.0.RELEASE.jar (必须)
spring-instrument-4.3.0.RELEASE.jar
spring-instrument-tomcat-4.3.0.RELEASE.jar
spring-jdbc-4.3.0.RELEASE.jar
spring-jms-4.3.0.RELEASE.jar
spring-messaging-4.3.0.RELEASE.jar
spring-orm-4.3.0.RELEASE.jar
spring-oxm-4.3.0.RELEASE.jar
spring-test-4.3.0.RELEASE.jar
spring-tx-4.3.0.RELEASE.jar
spring-web-4.3.0.RELEASE.jar (必须)
spring-webmvc-4.3.0.RELEASE.jar (必须)
spring-webmvc-portlet-4.3.0.RELEASE.jar
spring-websocket-4.3.0.RELEASE.jar
standard.jar
二、配置文件
(springMvc配置文件中默认配置文件路径是WEB-INFO里面并且命名规范是 [servlet-name]-servlet.xml )
2.1、通过xml配置
(1)自己创建HelloController类实现Controller接口(是import org.springframework.web.servlet.mvc.Controller;包里的接口)
(2)配置web.xml中DispatcherServlet
(3)配置springmvc-servlet.xml
<3.1>、配置mapping
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/><3.2>、配置adapter
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
(这里的Adapter配置是后面的处理器配置时name属性可以不需要写hello.do中的.do,如果这里省略了adapter的配置则 后面的配置就必须有 .do 否则无法找到对应的controller)
<3.3>、配置渲染器<!--配置渲染器 查找官方文档 22.5.2 Chaining ViewResolvers--> <!--http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-redirecting--> <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <!--结果视图前缀 在web-info地下建jsp包--> <property name="prefix" value="/WEB-INF/jsp/"/> <!--结果视图后缀--> <property name="suffix" value=".jsp"/> </bean>
<3.4>、配置请求和处理器
<bean name="/hell.do" class="com.lin.controller.HelloController"/>
(4)在WEB-INFO目录下建立目录jsp,并创建hello.jsp文件,通过ER表达式接收来自controller的参数进行渲染
2.2、通过注解方式配置
(1)自己创建HelloController类,添加注解 @controller @RequestMapping("/hello") (这里的hello相当于第一种方法在配置文件中配置的hello.do)
(2)、配置wen.xml中的DispatcherServlet
<servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>namespace:mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>这里红色字体是对 DispatcherServlet 的 contextConfigLocation 属性进行自定义,将默认的 [servlet-name]-servlet.xml文件重命名为mvc.xml 且目录改为src目录
(3)、配置mvc.xml (就是前面讲的 [servlet-name]-servlet.xml 核心文件)
<3.1>.配置视图渲染器(同上)
<3.2>. 配置扫描注解
<!--配置扫描器--> <context:component-scan base-package="com.lin.controller"/>
(4)、在WEB-INFO目录创建jsp目录,创建渲染的视图( 同上)
2.3、给URL分配bean
(1)、创建controller类同上第一种
(2)、web.xml 同上第一种
(3)、配置springmvc-servlet.xml
<3.1>.添加视图渲染器(同上)
<3.2>.给URL分配bean
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <!--key对应url请求名 value对应controller处理器的id--> <prop key="/hello*.do">helloControll</prop> </props> </property> </bean><3.3>.配置处理器
<!--通过hello*.do都可以匹配--> <bean id="helloControll" class="com.lin.controll.HelloControll"/>
(4)、创建视图 (WEB-INFO/jsp/hello.jsp) (同上)
2.4、给URL匹配bean
(1)、创建controller 同第一种
(2)、配置web.xml
<servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
(3)、配置springmvc-servlet.xml
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <!--结果视图前缀 在web-info地下建jsp包--> <property name="prefix" value="/WEB-INF/jsp/"/> <!--结果视图后缀--> <property name="suffix" value=".jsp"/> </bean> <!--给URL匹配bean--> <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/> <!--通过hello*.do都可以匹配--> <bean id="helloController" class="com.lin.controller.HelloController"/>
(4).创建视图文件同上
(以上便是通常的配置方式了,最后一种现在已经不推荐使用了)
spring官方查看文档:http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/
2.返回结果
springmvc对结果返回方式:
1.controller
@Controller public class HelloController{ @RequestMapping("/hello") public void hello(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { //不需要视图渲染器 //不需要视图渲染器实现数据显示 // resp.getWriter().println("use HttpServletResponse API"); //通过HttpServletResponse对象实现跳转 // resp.sendRedirect("index.jsp"); //HttpServletRequest实现转发 req.setAttribute("msg","HttpServletRequest forward"); req.getRequestDispatcher("index.jsp").forward(req,resp); } @RequestMapping("/hello1") public String hello(){ //不需要视图渲染器 //http://localhost:8080/hello1.do //实现转发1 (地址不变) //return "index.jsp"; //显示index.jsp //实现转发2 //return "forward:index.jsp"; //显示index.jsp //实现重定向 (地址发生改变) return "redirect:index.jsp"; } @RequestMapping("/hello2") public String hello2(){ //http://localhost:8080/hello2.do //实现转发 return "hello"; //转发到 WEB-INFO/jsp/hello.jsp //实现重定向 //return "redirect:hello.do"; //重定向到 hello.do 会把值传递过去 //实现转发 //return "forward:hello1.do"; //相当执行hello1.do 地址栏不变 } }
2.web.xml:
<servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
3.Springmvc-servlet.xml
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <!--结果视图前缀 在web-info地下建jsp包--> <property name="prefix" value="/WEB-INF/jsp/"/> <!--结果视图后缀--> <property name="suffix" value=".jsp"/> </bean> <!--开启注解扫描--> <context:component-scan base-package="com.lin.controller"/>c ontroller中的前两个方法不需要配置视图渲染器
3.数据处理
1.提交数据的处理(这里用注解的方式,不需要视图渲染器)
@Controller public class HelloController { @RequestMapping("/hello") public String hello(String name){ //不需要视图渲染器 传递普通字符串 //域名称和方法参数一致就行,http://localhost:8080/hello.do?name=zhangs // 不一致时 可以这样:public String hello(@RequestParam("uName")String name){ 则域名称就用uName了 //http://localhost:8080/hello.do?uName=zhangs System.out.println(name); return "index.jsp"; } //当提交的是个对象时,只要参数是个对象名就行,域名用对象属性名 @RequestMapping("/user") public String user(User user){ //http://localhost:8080/user.do?name=tony&pwd=123456 System.out.println(user); return "index.jsp"; }
1.1.提交的域名称和处理方法的参数名一致即可:
提交的数据:http://localhost:8080/hello.do?name=zhangs
处理方法:
@RequestMapping("/hello") public String hello(String name){ //不需要视图渲染器 传递普通字符串 //域名称和方法参数一致就行,http://localhost:8080/hello.do?name=zhangs // 不一致时 可以这样:public String hello(@RequestParam("uName")String name){ 则域名称就用uName了 //http://localhost:8080/hello.do?uName=zhangs System.out.println(name); return "index.jsp"; }
1.2.提交的域名称和处理方法的参数名不一致时:
提交的数据:http://localhost:8080/hello.do?username=zhangs
处理方法:
@RequestMapping("/hello") public String hello(@RequestParam("username") String name){ //不需要视图渲染器 传递普通字符串 // 不一致时 可以这样 则域名称就用username了 System.out.println(name); return "index.jsp"; }
1.3.提交的是个对象,只要方法参数是个对象,域名用对象属性名
提交的数据:http://localhost:8080/user.do?name=tony&pwd=123456
处理的方法:
@RequestMapping("/user") public String user(User user){ //http://localhost:8080/user.do?name=tony&pwd=123456 System.out.println(user); return "index.jsp"; }
User实体类:
public class User { private int id; private String name; private String pwd; 省略get\set }
2.将数据显示到UI层:
第一种方式:ModelAndView ---需要配置视图渲染器
public class HelloController implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { ModelAndView mv=new ModelAndView(); //封装要显示到视图中的数据 //相当于:httpServletRequest.setAttribute("msg","hello springmvc!"); mv.addObject("msg","hello springmvc!"); //视图名 mv.setViewName("hello"); //加上结果视图的前、后缀相当于找 web-info/jsp/hello.jsp return mv; } }
第二种方式:ModelMap ---不需要视图渲染器
ModelMap需要作为参数
//通过ModelMap将数据显示到UI层 @RequestMapping("/hello2") public String user(String name,ModelMap model){ //http://localhost:8080/hello2.do?name=aliyun //相当于 Request.setAttribute("name",name); model.addAttribute("name", name); System.out.println(name); return "index.jsp"; }
ModelAndView和ModelMap异同点:
相同点:两者都可将数据传递到UI层,通过er表达式接收 :${name}
不同点:ModelAndView 可以指定跳转的视图,而ModelMap不可以;ModelAndView 需要视图渲染器,Modelmap不需要配置。
1.通过web.xml文件配置过滤器解决:springmvc中提供CharacterEncodingFilter解决post乱码:
<filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
如果是get乱码:
a) 修改Tomcat的配置解决
b)自定义乱码解决的过滤器
2.restful风格 url
优点:轻量级,安全,效率高。
实现方式:
//restful风格 @RequestMapping("/{id}/{uid}/delete") public String hello2(@PathVariable int id,@PathVariable int uid){ //http://localhost:8080/12/45/delete.do id=12 uid=45 System.out.println("id="+id); //这里会根据变量名自动匹配,参数顺序没有要求 System.out.println("uid="+uid); return "index.jsp"; } @RequestMapping("/delete/{id}/{uid}") public String hello3(@PathVariable int id,@PathVariable int uid){ //这种情况,值放在后面,则 .do 需要放在参数值后面写 // http://localhost:8080/delete/12/54.do id=12 uid=54 System.out.println("id="+id); //这里会根据变量名自动匹配,参数顺序没有要求 System.out.println("uid="+uid); return "index.jsp"; }
5.文件上传
在原来springmvc基础jar包上再添加者两个jar问文件:
commons-fileupload-1.3.1.jar
commons-io-2.2.jar
1.springmvc-servlet.xml配置文件只需要配置文件上传解析器和注解扫描:
<!--配置文件上传解析器--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="utf-8"></property> <property name="maxUploadSize" value="10485760000"></property><!--最大文件大小--> <property name="maxInMemorySize" value="40960"></property><!--最大缓存大小--> </bean> <!--开启注解扫描--> <context:component-scan base-package="com.lin.controller"/>
2.web.xml配置DispatcherServlet
3.前台界面
①单文件上传
fileupload.jsp
<body> <%--这里必须是 post 方法 --%> <form action="upload.do" method="post" enctype="multipart/form-data"> file: <input type="file" name="file"/> <input type="submit" value="上传"> </form> </body>单文件上传后台处理的controller方法:
@RequestMapping("/upload") // @RequestParam("file")这个必须添加,否则抛异常 public String fileUpload(@RequestParam("file")CommonsMultipartFile file, HttpServletRequest request) throws IOException { //获取文件名 //file.getOriginalFilename(); String path=request.getRealPath("/fileupload"); //获取上传文件路径 System.out.println("path= "+path); InputStream is=file.getInputStream(); OutputStream os=new FileOutputStream(new File(path,file.getOriginalFilename())); int len=0; byte [] buffer=new byte[400]; //缓存区设置为400 while(((len=is.read(buffer))!=-1)) os.write(buffer,0,len); os.close(); is.close(); return "/index.jsp"; }
②文件批量上传:
fileupload2.jsp
<body> <h1>实现批量上传</h1><br/> <%--这里必须是 post 方法 --%> <form action="batch.do" method="post" enctype="multipart/form-data"> file: <input type="file" name="file"/> <br/> file: <input type="file" name="file"/><br/> <input type="submit" value="上传"><br/> </form> </body>文件批量上传后台处理controller方法:
@RequestMapping("/batch") // @RequestParam("file")这个必须添加,否则抛异常 public String fileUpload2(@RequestParam("file")CommonsMultipartFile file[], HttpServletRequest request) throws IOException { String path=request.getRealPath("/fileupload"); //获取上传文件路径 System.out.println("path= "+path); for(int i=0;i<file.length;i++){ InputStream is=file[i].getInputStream(); OutputStream os=new FileOutputStream(new File(path,file[i].getOriginalFilename())); int len=0; byte [] buffer=new byte[400]; while(((len=is.read(buffer))!=-1)) os.write(buffer,0,len); os.close(); is.close(); } return "/index.jsp"; }