SpringMVC
什么是MVC:MVC是模型(Model),视图(View),控制器(Controller)的简称,是一种软件设计规范
为什么要学习SpringMVC:轻量级,高效,约定大于配置(与Maven相同)
中心控制器:Spring的Web框架围绕DispatcherServlet设计,它的作用是将请求分发到不同的处理器,解析用户的请求并将其转换成一个模型返回给视图解析器
执行原理:用户发起一个请求,会请求到前端控制器DispatcherServlet,前端控制器会根据这个请求找到映射器,根据对应的bean找到对应的类,即适配这个映射器,接着这个类会返回一个MoudelAndView到视图解析器,它会根据返回的结果拼接得到一个跳转的地址,最后通过前端控制器渲染呈现给用户
java传统实现方法
1.新建一个moudle,并添加web支持
2.导入springmvc的相关依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
</dependencies>
3.配置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">
<!--配置DispatcherServlet,它是SpringMVC的核心,也叫前端控制器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<!--固定写法-->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--DispatcherServlet需要绑定一个Spring的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!--启动级别设置为1,随着服务器启动就启动-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--/ 匹配所有的请求,不包括.jsp-->
<!--/* 匹配所有的请求,包括.jsp-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
4.配置springmvc-servlet.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--处理器映射器-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<!--处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!--BeanNameUrlHandlerMapping根据请求的名字来找到对应的类-->
<bean id="/hello" class="controller.HelloController" />
</beans>
5.写具体的实现类
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 HelloController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView();
//业务代码
String res = "Hello!";
//封装
mv.addObject("msg",res);
//跳转
mv.setViewName("test");
return mv;
}
}
6.可能遇到的问题
(1).Tomcat运行时提示版本不能发行,检查发布项目的版本和java的版本是否一致
(2).jar包缺少,检查maven的项目依赖以及发布的项目中是否有lib包
注解实现
(建议使用maven直接以webapp模板方式创建子项目,可以避免很多问题)
1.实现注解需要的spring配置以及对应的命名空间
<!--自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
<context:component-scan base-package="controller" />
<!--让Springmvc不处理静态资源,如.css .js .html.....-->
<mvc:default-servlet-handler />
<!--实现自动装配,注入,取代了HandlerMapping和HandlerAdapter-->
<mvc:annotation-driven />
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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
2.例子
@Controller
public class ControllerTest1 {
@RequestMapping("/c1")
public String test1(Model model){
//封装数据
model.addAttribute("msg","ControllerTest1");
return "test"; //会被视图解析器处理,返回的值拼接后就是请求的url地址
}
@Controller:代表这个类会被Spring接管,被它注解的类,如果返回值是String并且有具体的页面可以跳转,那么就会被视图解析器解析
@RequestMapping("/c1"):可以理解为在地址栏请求c1时,就会解析到test.jsp这个页面
RestFul风格
@Controller
public class RestFulController {
//RestFul风格,地址栏:http://localhost:8080/add/1/2
@GetMapping("/add/{a}/{b}") //限定为Get方式请求,参数加上@PathVariable注解,可以在Mapping上传参,即地址栏上传参
public String test1(@PathVariable int a, @PathVariable int b, Model model){
int res = a + b;
model.addAttribute("msg","结果为"+res);
return "test";
}
}
SpringMVC中的转发和重定向
转发:forward,不写会走视图解析器,显式的加上则不会走视图解析器
重定向:redirect,不会走视图解析器,因为浏览器没有权限访问WEB-INF下的资源
//重定向
@RequestMapping("/M1/t2")
public String test2(){
return "redirect:/index.jsp";
}
传值与数据回显1:传的值为参数
@GetMapping("/t1")
//localhost:8080/t1?name=xxx
//@RequestParam:显式的限定前端传的参数名必须为username,到了后台会自动转化为name,统一高效!
public String test1(@RequestParam("username") String name, Model model){
//1.接受前端传来的参数
System.out.println("接收到的前端参数name为"+name);
//2.将返回的结果传递给前端
model.addAttribute("msg",name);
//3.跳转视图
return "test";
}
传值与数据回显2:传的值为对象,参数名要与实体类中的参数名一一对应
@GetMapping("/t2")
public String test2(User user){
System.out.println(user);
return "test";
}
使用Model封装数据
@GetMapping("/t3")
public String test3(@RequestParam("username") String name,ModelMap mp){
//封装要显示到视图中的数据
mp.addAttribute("name",name);
System.out.println(name);
return "test";
}
JSON
1.导包
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
2.1 使用例子1:返回一个普通用户对象
@RequestMapping("/j1")
@ResponseBody //不会走视图解析器,直接返回一个字符串
public String json1() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
User user = new User(1, "yuu", 18);
String str = mapper.writeValueAsString(user);
return str;
}
2.2 使用例子2:返回一个时间对象
@RequestMapping("/j2")
@ResponseBody //不会走视图解析器,直接返回一个字符串
public String json2(){
Date date = new Date();
//时间解析后的默认格式为时间戳Timestamp
return JsonUtils.getJson(date,"yyyy-MM-dd HH:mm:ss");
}
2.3 Json对象,时间工具类
public class JsonUtils {
public static String getJson(Object object,String dataFormat){
ObjectMapper mapper = new ObjectMapper();
//不使用时间戳的方式
mapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS,false);
//自定义日期格式,前端传什么日期就用什么日期格式
SimpleDateFormat sdf = new SimpleDateFormat(dataFormat);
mapper.setDateFormat(sdf);
try {
return mapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
//重载
public static String getJson(Object object){
return getJson(object,"yyyy-MM-dd HH:mm:ss");
}
}
3.若是只需要返回一个字符串,可以将@Controller换成@RestController,或者在方法上加一个@ResponseBody注解