时间:2025-03-12 22:59
人气:
作者:admin
ssm:spring+springmvc+mybatis MVC三层架构
Spring:IOC 和 AOP
SpringMVC:SpringMVC的执行流程!
MVC:模型(dao,service),视图(jsp),控制器(Servlet)
pojo:实体类,如User
vo:视图层的对象实体类,如UserVo
dto:数据传输的时候的对象实体类,如UserDto
SpringMVC特点:
Spring的web框架围绕DispatcherServlet设计。DispatcherServlet的作用是将请求分发到不同的处理器。从Spring2.5开始,使用java5或以上版本的用户可以采用注解的controller声明方式
快速入门:
在web.xml配置
<!--注册DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--关联一个springmvc配置文件:springmvc-servlet.xml-->
<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>
新建一个配置文件spring-mvc.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--处理器映射器-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--视图解析器:DispatcherServlet给他的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
写一个Controller类
public class HelloController implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//ModelAndView 模型和视图
ModelAndView mv = new ModelAndView();
// 封装对象,放在ModelAndView中
mv.addObject("msg","HelloSpringMVC!");
// 封装要跳转的视图,放在ModelAndView中
mv.setViewName("hello");
return mv;
}
}
编辑配置文件spring-mvc.xml,将Controller类放入IOC中
<bean id="/hello" class="cn.codewei.controller.HelloController"/>
编写jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${pageContext.request.getAttribute("msg")}
</body>
</html>
可能遇到的问题:访问出现404,排查步骤:
查看控制台输出,看一下是不是缺少了什么jar包
如果jar包存在,显示无法输出,就在IDEA项目结构中,添加lib依赖

重启tomcat,即可解决


实际开发中,我们不会这么去做,我们一般通过注解来实现!!
在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>
</web-app>
在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
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--自动扫描包,让指定包下的注解生效,由IOC统一管理-->
<context:component-scan base-package="cn.codewei.controller"/>
<!--让springmvc不再处理静态资源-->
<mvc:default-servlet-handler/>
<!--
支持mvc注解驱动
在spring中一般采用@RequestMapping注解来完成映射
要想使@RequestMapping生效
必须向上下文注册DefaultAnnotationHandlerMapping
和一个AnnotationMethodHandlerAdapter实例
这两个实例分别在类级别和方法级别处理
而annotation-driver配置帮助我们自动完成上述两个实例的注入
-->
<mvc:annotation-driven/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
在视图解析器中我们把所有视图都存放在/WEB-INF/目录下,这样可以保证视图安全,因为这个目录下的文件,客户端不能直接访问
编写一个Controller类
@Controller //代表这个类会被springIOC托管,被这个注解的类中的所有方法,如果返回值是String,并且由具体的页面可以跳转,那么就会被视图解析器解析
@RequestMapping("/hello")
public class HelloController {
@RequestMapping("/controllerhello")
public String Controllerhello(Model model){
// 封装数据
model.addAttribute("msg","HelloSrpingMVC!");
return "hello"; // 被视图解析器处理
}
}
SpringMVC必须配置的三大件:
处理器映射器,处理器适配器,视图解析器
实现接口Controller定义控制器是较老的办法
缺点是:一个控制器只有一个方法,如果要多个方法则需要定义多个Controller
@Component 组件
@Service serivce层
@Controller controller层
@Repository dao层
RestFul就是一个资源定位及资源操作的风格,不是标准也不是协议,只是一种风格
使用RestFul操作资源:可以通过不同的请求方式来实现不同的效果!
如下:请求地址一样,但是功能可能不同
http://127.0.0.1/item/1 查询,GET
http://127.0.0.1/item 新增,POST
http://127.0.0.1/item 更新,PUT
http://127.0.0.1/item/1 删除,DELETE
原来的:http://localhost:8080/add?a=2&b=3
RestFul:http://http????/localhost:8080/add/1/2
在SpringMVC中可以使用@PathVariable注解,让方法参数的值对应绑定到一个URI模板变量上
@Controller
public class RestFulController {
@RequestMapping("/add/{a}/{b}")
public String test(@PathVariable int a,@PathVariable int b, Model model){
int result = a +b;
model.addAttribute("msg","执行了add方法!"+result);
return "login";
}
}
可以通过设置method来设置请求的的方式,如只能通过GET方式访问的到:
@Controller
public class RestFulController {
@RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET)
public String test(@PathVariable int a,@PathVariable int b, Model model){
int result = a +b;
model.addAttribute("msg","执行了add方法!"+result);
return "login";
}
}
可是使用注解来设置允许请求的方式,如
@Controller
public class RestFulController {
@GetMapping("/add/{a}/{b}")
public String test(@PathVariable int a,@PathVariable int b, Model model){
int result = a +b;
model.addAttribute("msg","执行了add方法!"+result);
return "login";
}
}
@GetMapping("/add/{a}/{b}")
@PostMapping("...")
@DeleteMapping("...")
@PutMapping("...")
通过设置访问方式的约束,可以来实现通过相同的URL,不同的访问方式,得到的访问结果是不同的
结果跳转方式:
页面:{视图解析器前缀}+名字{视图解析器后缀}
方式一:可能通过原生的HttpServletRequest request, HttpServletResponse response的形式
@Controller
public class ModelTest1 {
@GetMapping("/modelTest1")
public String test1(HttpServletRequest request, HttpServletResponse response){
request.setAttribute("msg","helloModelTest1!");
return "test";
}
}
方式二:不再配置视图解析器
删除springmvc.xml中的配置
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
通过return 来实现转发或重定向
@Controller
public class ResultSpringMVC{
@RequestMapping("/rsm/t1")
public String test1(){
// 转发
return "/index.jsp";
}
@RequestMapping("/rsm/t2")
public String test2(){
// 转发二
return "forward:/index.jsp";
}
@RequestMapping("/rsm/t3")
public String test3(){
// 重定向
return "redirect:/index.jsp";
}
}
方式三:有视图解析器时,转发和重定向(经常使用)
在有视图解析器时,转发,直接写转发到的文件的名字,重定向,加上前缀,写上路径,如
return "redirect:/index.jsp"; //重定向
return "index"; // 转发
1. 提交的参数名称和处理方法的参数名一致
如:localhost:8080/hello?name=codewei
处理方法:
@RequestMapping("/hello")
public String hello(String name){
...;
return "...";
}
2. 提交的参数名和处理的参数名不一致
如:localhost:8080/hello?username=codewei
处理方法:
@RequestMapping("/hello")
public String hello(@RequestParam("usermae") String name){
...;
return "...";
}
3. 提交的是一个对象
如:localhost:8080/hello?name=codewei&id=1&age=20
封装成一个实体类
public class User {
private int id;
private String name;
private int age;
...;
}
处理方法
@Controller
public class UserControllerTest {
@RequestMapping("/user")
public String userTest(User user, Model model){
model.addAttribute("user",user);
return "login";
}
}
方式一:通过ModelAndView
public class HelloController implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mv = new ModelAndView();
String result = "HelloSpringMVC!";
mv.addObject("msg",result);
mv.setViewName("test");
return mv;
}
}
方式二:通过Model(通常使用Mode)
@Controller
public class UserControllerTest {
@RequestMapping("/user")
public String userTest(User user, Model model){
model.addAttribute("user",user);
return "login";
}
}
方式三:通过ModelMap
继承了LinkedMap的方法和特性,和Model用法基本一样
LinkedHashMap-->ModelMap-->Model
可以解决过滤器Filter解决
@WebFilter("/*")
public class EncodingFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
filterChain.doFilter(servletRequest,servletResponse);
}
public void destroy() {
}
}
使用springmvc,我们可以不再像之前一样写Filter过滤器类了,我们可以直接在web.xml配置
<!--配置过滤器:utf-8-->
<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>
JSON乱码问题解决:
可通过注解@RequestMapping中的一个参数进行设置,如
@RequestMapping(value="/j1",produces="application/json;charset=utf-8")
但是我们一般不会这么做
我们在spring-mvc.xml中的mvc:annotation-driven中进行配置
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
@ResponseBody // 它就不会走视图解析器,会直接返回一个字符串
@Controller
public class UserController {
@ResponseBody // 它就不会走视图解析器,会直接返回一个字符串
public String json1(){
return "test";
}
}
这样return就是单纯的返回一个字符串
@RestController //放在类上,该类下所有方法只会返回JSON字符串,不会走视图解析器
@Controller
@RestController // 该类下所有方法只会返回JSON字符串,不会走视图解析器**
public class UserController {
@GetMapping("/j1")
public String json1() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
User user = new User(1,"唐嫣",33);
String s = objectMapper.writeValueAsString(user);
return s;
}
}
Json工具类
public class JsonUtils {
// json工具类 获取json
public static String getJson(Object object){
return getJson(object,"yyyy-MM-dd HH:mm:ss");
}
public static String getJson(Object object,String dateFormat){
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
mapper.setDateFormat(sdf);
try {
return mapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}
自定义拦截器类,就必须实现HandlerInterceptor接口
public class MyInterceptor implements HandlerInterceptor {
// return true;放行 执行下一个拦截器
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("=====处理前===========");
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("============处理后============");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("===========清理==========");
}
}
在springmvc.xml中配置拦截器
<mvc:interceptors>
<mvc:interceptor>
<!--包括这个请求下面的所有请求-->
<mvc:mapping path="/**"/>
<bean class="cn.codewei.config.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
在前端页面要设置表单中的enctype属性
1. 导入jar包
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
2. 配置
SpringMVC为文件上传提供了直接的支持,这种支持是即插即用的MultipartResolver实现的
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--请求编码格式,必须和jsp的pageEncoding一致-->
<property name="defaultEncoding" value="utf-8"/>
<!--上传文件大小限制 单位为字节-->
<property name="maxUploadSize" value="10485760"/>
<property name="maxInMemorySize" value="40960"/>
</bean>
3. 上传文件:方式一
@RestController
public class FileController {
@RequestMapping("/upload")
public String fileUpload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
// 获取文件名
String filename = file.getOriginalFilename();
// 如果文件为空,直接回到首页
if ("".equals(filename)){
return "redirect:/index.jsp";
}
System.out.println("上传文件名:" + filename);
// 上传路径保存设置
String path = request.getRealPath("/upload");
// 如果路径不存在,创建一个
File realPath = new File(path);
if (!realPath.exists()){
realPath.mkdir();
}
System.out.println("上传文件保存地址:" + realPath);
InputStream is = file.getInputStream(); // 文件输入流
FileOutputStream os = new FileOutputStream(new File(realPath, filename)); //文件输出流
// 读取写出
int len=0;
byte[] bytes = new byte[1024];
while((len =is.read(bytes))!=-1){
os.write(bytes,0,len);
os.flush();
}
os.close();
is.close();
return "redirect:/index.jsp"
}
}
4. 上传文件:方式二
@RestController
public class FileController {
@RequestMapping("/upload")
public String fileUpload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
// 上传路径保存设置
String path = request.getRealPath("/upload");
File realPath = new File(path);
if (!realPath.exists()){
realPath.mkdir();
}
// 通过CommonsMultipartFile的方法直接写文件
file.transferTo(new File(realPath+"/"+file.getOriginalFilename()));
return "redirect:/index.jsp";
}
}
Hutool 的 `TimedCache` 到期会自动清理吗?