Controller
1. 实现 Controller 接口
不需要处理器映射器适配器。
ControllerTest1.java
package com.klaus.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ControllerTest1 implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 待返回的 Model 和 View
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("msg", "Hello SpringMVC - 01");
modelAndView.setViewName("test");
return modelAndView;
}
}
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 不需要处理器映射器适配器 -->
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean name="/hello" class="com.klaus.controller.ControllerTest1"/>
</beans>
2. 注解
使用 Controller 注解时说明该类被 spring 接管,如果类中的方法返回类型是 String 并且有具体页面可以返回,那么就可以被解析,不需要处理器映射器适配器。
可以使用@RequestMapping
实现同一个类中不同方法的不同映射。
@Component // 组件
@Service // Service
@Repository // dao
@Controller //controller
要使用注解,就要让Spring能够扫描到注解,需要再配置文件中声明扫描:
<!--自动扫描包中的类,注解类会被交给IOC容器管理-->
<context:component-scan base-package="com.klaus.controller"/>
ControllerTest2.java
package com.klaus.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller // 该类被 spring 接管,如果类中的方法返回类型是 String 并且有具体页面可以返回,那么就可以被解析
public class ControllerTest2 {
@RequestMapping("/hello2")
public String test2(Model model){
model.addAttribute("msg", "Hello SpringMVC - 02");
return "test";
}
@RequestMapping("/hello3")
public String test3(Model model){
model.addAttribute("msg", "Hello SpringMVC - 03");
return "test";
}
}
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--自动扫描包中的类,注解类会被交给IOC容器管理-->
<context:component-scan base-package="com.klaus.controller"/>
<!-- <bean name="/hello" class="com.klaus.controller.ControllerTest1"/>-->
</beans>
RequestMapping
用于映射 url 到控制器类或一个特定处理程序方法,可以用在类上也可以用在方法上。用在方法上的和前面一样,主要是用在类上的,使用方法是:上下文 + 类路径 + 方法路径,下面方法的访问路径就是:http://localhost:8080/springmvc05/hello4/hello3
。
package com.klaus.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/hello4")
public class ControllerTest3 {
@RequestMapping("/hello3")
public String test4(Model model){
model.addAttribute("msg", "Hello SpringMVC - 04");
return "test";
}
}
RestFul风格
将互联网中所有的事务都抽象为资源。
使用 RestFul 可以通过不同的请求方式(GET,POST,PUT,DELETE 对应增删改查)实现不同的资源请求。用请求方式控制操作,而不是不同的 url。
上面说了是根据请求方式控制操作的,所以在 RequestMapping 中,除了映射路径,还要指明请求方式,如@RequestMapping(name = "/add/{a}/{b}",method = RequestMethod.DELETE)
,但由于较长,对于常用的几个方式有专门的注解如@GetMapping, @PostMapping
。参数a,b通过 @PathVariable
注解传入。
package com.klaus.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
@Controller
public class RestFulController {
//@RequestMapping(name = "/add/{a}/{b}",method = RequestMethod.DELETE)
@GetMapping("/add/{a}/{b}")
public String test5(@PathVariable int a, @PathVariable int b, Model model){
int res = a+b;
model.addAttribute("msg", "结果为1" + res);
return "test";
}
@PostMapping("/add/{a}/{b}")
public String test6(@PathVariable int a, @PathVariable int b, Model model){
int res = a+b;
model.addAttribute("msg", "结果为2" + res);
return "test";
}
}
重定向和转发
不再需要视图解析器了,springmvc本身就可以(因为是 Servlet )。方法是直接 return 到要访问资源,默认方式是转发,如果要进行跳转,使用 redirect: 进行特殊说明,如return "redirect:/index.jsp";
。
注:此时如果有视图解析器并不做特殊说明时重定向的话,视图解析器依然会生效。
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--自动扫描包中的类,注解类会被交给IOC容器管理-->
<context:component-scan base-package="com.klaus.controller"/>
</beans>
ModelTest1.java
package com.klaus.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class ModelTest1 {
@RequestMapping("/helloModel")
public String test(Model model){
model.addAttribute("msg", "Hello SpringMVC Model&View");
return "/WEB-INF/jsp/test.jsp";
}
}
数据处理
接收前端参数
-
表单域名称 和 Controller 中方法的参数名称相同,此时可以直接获得前端的数据。
package com.klaus.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/user") public class UerController { @GetMapping("/test1") public String test1(String name, Model model){ // 接受前端参数 System.out.println("接收到:" + name); // 结果传给前端 model.addAttribute("msg", name); // 视图跳转 return "test"; } }
此时使用
http://localhost:8080/springmvc05/user/test1?name=liu
可以正确访问视图。
-
名称不相同,使用 @RequestParam注解。
如果在第一种情况下使用 http://localhost:8080/springmvc05/user/test1?username=liu 时,跳转到 test.jsp 页面后不会有参数 liu 的显示,因为它只能默认接受前端传来的名为 name 的参数,要解决这个问题,使用 @RequestParam 注解:package com.klaus.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller @RequestMapping("/user") public class UerController { @GetMapping("/test1") public String test1(@RequestParam("username") String name, Model model){ // 接受前端参数 System.out.println("接收到:" + name); // 结果传给前端 model.addAttribute("msg", name); // 视图跳转 return "test"; } }
-
传送对象
当前端接受对象类型数据时,和普通类型一样,方法参数为同类型同名的变量,如果传递的对象 User 中各个字段名和类中的一样,那么直接使用,否则匹配不到,对应值为 null。
例:
package com.klaus.controller; import com.klaus.pojo.User; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller @RequestMapping("/user") public class UerController { @GetMapping("/test2") public String test2(User user, Model model){ System.out.println("接收到:" + user); model.addAttribute("msg", user); return "test"; } }
例如
使用http://localhost:8080/springmvc05/user/test2?name=liu&age=1&id=1 得到的是user{id=1, name='liu', age=1} 使用http://localhost:8080/springmvc05/user/test2?username=liu&age=1&id=1 得到的只是User{id=1, name='null', age=1}
原因就是后者传入的 username 和类中的 name 不匹配。
## 数据回显
-
ModelAndView
最初用到的。
-
Model
前面常用到的。ModelMap 的精简版。
-
ModelMap
继承了 LinkedHashMap,拥有 LinkedHashMap 的全部功能。
乱码
前端传来中文时,到了后台就会乱码。
解决方式一:过滤器
form.jsp 前端页面提交中文数据
<%--
Created by IntelliJ IDEA.
User: klaus
Date: 2021/8/5
Time: 16:37
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/springmvc05/Encoding/test" method="post">
<input type="text" name="name" >
<input type="submit">
</form>
</body>
</html>
com.klaus.controller.EncodingController.java,接收数据,跳转页面
package com.klaus.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class EncodingController {
@PostMapping("/Encoding/test")
public String test1(String name, Model model){
model.addAttribute("msg", name);
return "test";
}
}
com.klaus.filter.MyFilter.java,过滤器,解决乱码
package com.klaus.filter;
import javax.servlet.*;
import java.io.IOException;
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
chain.doFilter(request,response);
}
@Override
public void destroy() {
}
}
web.xml,进行注册
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--过滤器,解决乱玛-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>com.klaus.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
解决方式二:springmvc内置乱码过滤
使用SpringMVC提供的乱码过滤器,这样就不用自己写 MyFilter.java 了。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 过滤器 -->
<filter>
<filter-name>encoding</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>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>