一. 认识SpringMVC
-
SpringMVC是一个基于MVC模式的WEB/表现层框架,它解决WEB开发中常见的问题:参数接收、文件上传/下载、表单验证、国际化等等;
-
SpringMVC作为Spring框架一个非常重要的功能模块,可以与Spring无缝集成,提高开发效率;
-
Spring是一个轻量级的Java 开发框架,为了解决企业应用开发的复杂性而创建。SpringMVC以Spring框架为核心,为应用程序中的Web层(表现层)提出的一套优秀的解决方案;
-
目前很多公司都使用SpringMVC,90%的招聘单位要求熟悉使用SpringMVC;
注意:SpringMvc的功能就是之前Servlet的功能,可以理解为使用SpringMVC代替了Servlet;
二.SpringMVC项目搭建
2.1 导入jar包
spring-aop-4.1.2.RELEASE.jar
spring-beans-4.1.2.RELEASE.jar
spring-context-4.1.2.RELEASE.jar
spring-core-4.1.2.RELEASE.jar
spring-expression-4.1.2.RELEASE.jar
spring-test-4.1.2.RELEASE.jar
spring-web-4.1.2.RELEASE.jar
spring-webmvc-4.1.2.RELEASE.jar
(SpringMVC)commons-logging-1.1.1.jar
(日志)
2.2 配置web.xml文件
-
在web.xml中配置前端控制器
-
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>day38_springmvc</display-name> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
2.3 配置spring-mvc.xml
-
新建一个source floder存放
spring-mvc.xml
配置文件 -
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean name="/hello.do" class="cn.xxxx._01springmvc.HelloMvc"></bean> </beans>
-
新建一个类,该类实现
Controller
接口 -
通过该类在浏览器中进行测试,如果控制台收到消息,则表示项目搭建成功
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
public class HelloMvc implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
System.out.println("访问到了");
// TODO Auto-generated method stub
return null;
}
}
三. web.xml中前端控制器匹配方式
-
方式1:
*.do
:匹配范围太窄了 -
方式2:
/*
什么都拦截 匹配太大了,会拦截jsp -
方式3:
/
不拦截jsp,会拦截静态资源文件 推荐使用方式 -
配置
-
<servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <!-- *.xx注释范围太窄 --> <!-- <url-pattern>*.do</url-pattern> --> <!-- /* 什么都拦截,拦截范围太大,会拦截jsp --> <!-- <url-pattern>/*</url-pattern> --> <!-- / 不拦截jsp其他都会匹配,会拦截静态资源文件,js css 图片 --> <url-pattern>/</url-pattern> </servlet-mapping>
-
但是我们如果想要访问静态资源该怎么办呢?
-
在
spring-mvc.xml
进行配置静态资源放行 -
<mvc:default-servlet-handler/>
四.前端控制器的编写方式
4.1 方式一 实现Controller
4.2 方式二 实现HttpRequestHandler
//和方式一的实现模式相似
public class HiController implements HttpRequestHandler{
@Override
public void handleRequest(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("实现HttpRequestHandler...");
req.setAttribute("name", "红梅");
req.setAttribute("age", 18);
//转发 -- 因为要访问WEB-INF的资源 共享request作用域的数据
req.getRequestDispatcher("/WEB-INF/hello.jsp").forward(req, resp);
}
}
4.3 方式三 使用全注解
package cn.xxxx._03annotation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/longin")
public class Nomoal {
@RequestMapping("/sign")
public void sign(){
System.out.println("注册方法");
}
@RequestMapping("/update")
public void update(){
System.out.println("使用更新方法");
}
}
-
@Controller 控制层实例化对象注解
-
@RequestMapping 请求映射
-
需要在spirng-mvc.xml中配置扫描路径和启用注解支持
-
<!-- 扫描包路径:上下文组件扫描 ,Spring容器会去扫描cn.xxxx这个包及其子包中所有的类,如果发现类上有类似@Controller这样注解,就会创建该类的对象,并进行管理--> <context:component-scan base-package="cn.xxxx"></context:component-scan> <!-- 开启Spring对Mvc的支持 = 能够使用@Requestmapping注解 --> <mvc:annotation-driven></mvc:annotation-driven>
五. 全注解
- 匹配请求
@RequestMapping
- 控制层实例化对象
@Controller
- 服务层实例化对象
@Service
- 持久层实例化对象
@Respository
- 普通类实例化对象
@Component
- 注入对象
@Autowired
- 自己写的类,通过注解交给Sprring管理
- 别人写的没法使用注解,只能使用配置
六. 接受请求参数
-
首先我们有这样一个jsp页面
-
<%@ page pageEncoding="utf-8"%> <!DOCTYPE html> <html> <head> <style type="text/css"> *{margin: 0px;padding: 0px;} div{width: 280px;border: 6px solid gray;} h3{background-color: black; color: white;} input{margin: 7px 0px;width: 150px;height: 22px;} form {float: left;margin: 10px;} a{font-size: 23px;margin: 10px;} </style> </head> <body> <h2>练习接收请求参数</h2> <a href="${pageContext.request.contextPath}/jsp/controller.jsp">点我回去赛</a> <hr> <%-- 获取请求参数示例1 --%> <form action="${pageContext.request.contextPath}/login/form1"> <div> <h3>登录1:HttpServletRequest接收</h3> 用户:<input name="name" value="tom1"/><br/> 密码:<input name="pwd" type="password"/><br/> <input style="margin-left: 50px;" value="登录1" type="submit"/> </div> </form> <%-- 获取请求参数示例2 --%> <form action="${pageContext.request.contextPath}/login/form2" method="get"> <div> <h3>登录2:通过参数接收</h3> 用户:<input name="name" value="tom2"/><br/> 密码:<input name="pwd" type="password"/><br/> <input style="margin-left: 50px;" value="登录2" type="submit"/> </div> </form> <%-- 获取请求参数示例3--%> <form action="${pageContext.request.contextPath}/login/form3" method="post"> <div> <h3>登录3:对象接收</h3> 用户:<input name="name" value="tom3"/><br/> 密码:<input name="pwd" type="password"/><br/> <input style="margin-left: 50px;" value="登录3" type="submit"/> </div> </form> <%-- 获取请求参数示例4 --%> <form action="${pageContext.request.contextPath}/login/form4/3/8"> <div> <h3>登录4:URL地址提取</h3> 用户:<input name="name" value="tom4" /><br/> 密码:<input name="pwd" type="password"/><br/> <input style="margin-left: 50px;" value="登录4" type="submit"/> </div> </form> </body> </html>
-
如何进行参数接收?
方式1:使用HttpServletRequest
-
方式1:使用HttpServletRequest
-
@Controller @RequestMapping("/login") public class GetPramController { @RequestMapping("/form1") public void getPram1(HttpServletRequest req){ String name = req.getParameter("name"); String password = req.getParameter("pwd"); System.out.println(name + "---------" +password); } }
方式2:使用两个参数接受
- 注意: 参数名应该和前台设置的name属性值一致
-
@RequestMapping("/form2") public void getPram2(String name, String pwd){ System.out.println(name+"-----"+pwd); }
方式3:使用类来接收
-
注意 类中的字段名应该和前台的标签设置的name属性值一致
-
User类:必须设置他的get和set属性(JavaBean中的读写属性)
-
public class User { private String name; private String pwd; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } @Override public String toString() { return "User [name=" + name + ", pwd=" + pwd + "]"; }
//方法 类中的字段名称要和页面中的字段名称一致
@RequestMapping("/form3")
public void getPram3(User user){
System.out.println(user);
}
方法四:Url地址栏提取
@RequestMapping("/form4/{cid}/{pwd}")
public void getPram4(@PathVariable("cid")String name, @PathVariable("pwd") String pwd){
System.out.println(name +"-----" +pwd);
}
七. 解决中文乱码问题
- 当浏览器使用post方法进行接收的时候,中文传入后台出现乱码问题
7.1 实现Filter
接口
-
新建一个Filter的实现类,通过在
init
方法中获取到字符编码,传入到doFilter
方法中并放行 -
web.xml
配置 和servlet相似,需要传入一个初始化参数 -
<filter> <filter-name>filter</filter-name> <filter-class>cn.xxxx._05Filter.MyFliter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
-
java代码
-
public class MyFliter implements Filter { /**字符编码*/ String encoding; @Override public void init(FilterConfig filterConfig) throws ServletException { //获取初始化参数 encoding = filterConfig.getInitParameter("encoding"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //设置字符编码 request.setCharacterEncoding(encoding); //设置放行 chain.doFilter(request, response); } @Override public void destroy() { } }
7.2 使用springmvc写好的过滤器
- 直接配置
web.xml
<filter>
<filter-name>characterEncoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- 这样就不用再去编写过滤器的代码了
八. 相应跳转向页面传值
8.1 使用HttpServletRequest传值
-
我们可以把需要传的值存入HttpServletRequest中,然后进行请求请求转发
-
@RequestMapping("/form5") public void sendPram5(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ req.setAttribute("message5", "日怪得很"); //传值使用请求转发 req.getRequestDispatcher("/jsp/model2.jsp").forward(req, resp); }
8.2 使用Model传值
-
我们可以使用框架中的Model类进行传值和跳转操作
-
@RequestMapping("/form6") public String sendPram6(Model model){ User user = new User(); user.setName("张无忌"); user.setPwd("殷素素"); //Model可以直接使用addAttribute方法直接传入一个object 在jsp页面代码接收名字默认为传入值的名字 //model.addAttribute(user); model.addAttribute("message6", user); //跳转返回的页面 return "/jsp/model2.jsp"; }
8.3 使用ModelAndView传值
-
我们同样可以使用框架里面的ModelAndView类来传值、跳转
-
@RequestMapping("/form7") public ModelAndView sendPram7(){ ModelAndView mav = new ModelAndView(); mav.addObject("message7", "狮王谢逊"); //设置页面跳转 mav.setViewName("/jsp/model2.jsp"); return mav; }
九. 配置视图解析器
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property><!-- 前缀prefix:会自动在返回值前面加个上/ -->
<property name="suffix" value=".jsp"></property><!—后缀suffix:会自动在返回值后面加个上.jsp -->
</bean>