Springmvc
springmvc 的工作流程
1 核心控制器接受用户请求
2 核心控制器根据 用户的 处理器映射器 找到相关的handler(handler里面包含拦截器以及我们写的hanlder
3 核心控制器 通过处理器适配器执行 相关的handler 并返回给ModelAndView
4 核心控制器吧这个交给视图解析器 视图解析器进行解析 返回view
5 核心控制器 填充数据渲染视图
6 核心控制器 返回东西给用户
Springmvc开发流程
1 在web.xml中配置核心控制器 接受请求 并配置相关过滤器
(1)针对jtomcat8.0 后的post方式的中文乱码配置如下
1 2 3 4 5 6 7 8 9 10 11 12 | <filter> <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> |
(2)核心控制器配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <servlet> <servlet-name>springDispatcherServlet</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> <!-- Map all requests to the DispatcherServlet for handling --> <servlet-mapping> <servlet-name>springDispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> |
2 在springmvc全局配置中 配置处理器映射器,配置处理器适配器 配置视图解析器
<!-- 1配置处理器映射器 -->
<!-- 我们这里使用注解处理器映射器 也就是说 我们后面的开发是基于注解的 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
<!-- 2配置处理器适配器 -->
<!-- 我们这里使用注解处理器映射器 凡是class上面有@controller的注解 注解处理器映射器都能够处理 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>
<!-- 3配置视图解析器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
第一步可以用<mvc:annotation-driven>代替。
<!-- 配置hander-->
要么用前面的方式配置适配器和映射器 要么用下面这种方式:
1 2 3 4 | <!-- 1 配置处理器映射器 --> <context:component-scan base- package = "com.cc.web" ></context:component-scan> <!-- 我们这里使用注解处理器映射器 也就是说 我们后面的开发是基于注解的 --> <mvc:annotation-driven></mvc:annotation-driven> |
配置试图解析器后默认走试图解析器中 如果需要走其他路径 则按下面操作:
1 | forward和redirect 中的 /均表示当前项目的的根 |
1 2 3 4 5 6 7 8 9 10 | @RequestMapping ( "/test" ) public String test(){ System.out.println( "thist is a test" ); return "forward:/index.jsp" ; } @RequestMapping ( "/test1" ) public String test1(){ System.out.println( "thist is a test" ); return "redirect:/index.jsp" ; } |
ModelAndView 用法
springmvc默认支持多类型的参数绑定。
默认支持哪些类型:
HttpServletRequest、response、session、Model(用于将数据填充到request域)
requestParam注解:用于绑定单个请参数的名称和方法形参名一致方可绑定。
public ModelAndView test2(@RequestParam(value="aaa") String aaa){ }
数据回写
1 简单数据回写
商品修改数据回显:
注意在进入修改页面的controller方法中和提交修改商品信息方法model.addAttribute方法设置的key一致。
2 pojo类型数据回显
ModelAndView andView = new ModelAndView();
andView.addObject("u", user);
// 设置页面的地址
andView.setViewName("/show_pojo.jsp");
使用@ModelAttribute,作用于将请求pojo数据放到Model中回显到页面
//会把该user对象填充到request中 并且名字叫做u
public ModelAndView reShowPojo(@ModelAttribute(value="u") User user)
使用@ModelAttribute将公用的取数据的方法返回值传到页面,不用在每一个controller方法通过Model将数据传到页面。
显示:
文件上传:
1 导入夹包
commons-fileupload-1.3.3.jar
commons-io-2.1.jar
2 在spring_mvc.xml中配置文件上传解析器
1 2 3 4 5 6 7 8 | <bean id= "multipartResolver" class = "org.springframework.web.multipart.commons.CommonsMultipartResolver" > <!-- 指定文件中文名的编码 --> <property name= "defaultEncoding" value= "UTF-8" /> <!-- 指定所上传文件的总大小,单位字节。注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和 --> <property name= "maxUploadSize" value= "3145728" /> </bean> |
3 写文件上传的表单项(注意文件上传的name属性 后面处理时需要和name同名)
1 2 3 4 | <form action= "${pageContext.request.contextPath }/fileup" method= "post" enctype= "multipart/form-data" > <input type= "file" name= "fi" ></br> <input type= "submit" value= "submit" > </form> |
4 文件上传逻辑处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | @Controller public class FileUp { @RequestMapping ( "/fileup" ) // file的name必须和方法的形参一致。并且表单的 public void file(MultipartFile fi,HttpServletResponse response) { System.out.println(fi.getOriginalFilename()); //直接写到某地各方 File dirFile = new File( "d:/upload/" +System.currentTimeMillis()+fi.getOriginalFilename()); if (!dirFile.exists()) { dirFile.mkdirs(); } try { fi.transferTo(dirFile); response.sendRedirect( "/mybatis_ddd/NewFile.jsp" ); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } |
Springmvc 配置不拦截静态资源
spring_mvc.xml中配置
1 2 3 4 5 6 7 8 9 10 11 | <!-- 资源映射 不拦截 的 静态资源 --> <mvc:resources location= "/" mapping= "/**/*.html" /> <mvc:resources location= "/" mapping= "/**/*.js" /> <mvc:resources location= "/" mapping= "/**/*.css" /> <mvc:resources location= "/" mapping= "/**/*.png" /> <mvc:resources location= "/" mapping= "/**/*.jpg" /> <mvc:resources location= "/" mapping= "/**/*.gif" /> <mvc:resources location= "/" mapping= "/**/*.eot" /> <mvc:resources location= "/" mapping= "/**/*.svg" /> <mvc:resources location= "/" mapping= "/**/*.ttf" /> <mvc:resources location= "/" mapping= "/**/*.woff" /> |
在处理器适配器中注入MappingJacksonHttpMessageConverter
让处理器适配器支持json数据解析,需要注入org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
需要导入三个夹包 jackson_annotation jackson_core jackson_databind
在springmvc.xml中配置(让处理器适配器支持json数据解析)
1 2 3 4 5 6 7 8 9 10 11 | <mvc:annotation-driven> <mvc:message-converters> <bean class = "org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" > <property name= "supportedMediaTypes" > <list> <value>application/json;charset=UTF- 8 </value><!-- 避免IE出现下载JSON文件的情况 --> </list> </property> </bean> </mvc:message-converters><br></mvc:annotation-driven> |
@requestBody注解的使用
1、@requestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,比如说:application/json或者是application/xml等。一般情况下来说常用其来处理application/json类型。
2、
通过@requestBody可以将请求体中的JSON字符串绑定到相应的bean上,当然,也可以将其分别绑定到对应的字符串上。
例如说以下情况:
$.ajax({
url:"/login",
type:"POST",
data:'{"userName":"admin","pwd":"admin123"}',
content-type:"application/json charset=utf-8",
success:function(data){
alert("request success ! ");
}
});
@requestMapping("/login")
public void login(@requestBody String userName,@requestBody String pwd){
System.out.println(userName+" :"+pwd);
}
这种情况是将JSON字符串中的两个变量的值分别赋予了两个字符串,但是呢假如我有一个User类,拥有如下字段:
String userName;
String pwd;
那么上述参数可以改为以下形式:@requestBody User user 这种形式会将JSON字符串中的值赋予user中对应的属性上
需要注意的是,JSON字符串中的key必须对应user中的属性名,否则是请求不过去的。
3、
在一些特殊情况@requestBody也可以用来处理content-type类型为application/x-www-form-urlcoded的内容,只不过这种方式
不是很常用,在处理这类请求的时候,@requestBody会将处理结果放到一个MultiValueMap<String,String>中,这种情况一般在
特殊情况下才会使用,
例如jQuery easyUI的datagrid请求数据的时候需要使用到这种方式、小型项目只创建一个POJO类的话也可以使用这种接受方式
1 2 3 4 5 6 | url : "${pageContext.request.contextPath }/ajax" , type : "post" , dataType : "json" , //contentType : "application/json", //contentType : "application/text", data:{ "username" : "John" , "password" : "Doe" }, 此时 不要用引号,不能设置contentType : "application/text" , // JSON.stringify(parms), public String requestJsson(String username, String password){ String name=request.getParameter("username")+request.getParameter("password"); //取不到值 System.out.println(username); //可以去到值username 应该和data 数据中的对应} |
public String requestJsson(@RequestBody String username,@RequestBody String password){
System.out.println(username);//会把上面的data数据全部显示出来 username=John&password=Doe&aa=bb
}
1 2 3 4 5 6 7 8 9 10 | //contentType : "application/text", contentType: 'application/json;charset=UTF-8' , //当传过去的置式json 时 注意这种写法的data 要用引号, data: '{ "username":"John" , "password":"Doe"}' , @RequestMapping (value= "/ajax" ,method=RequestMethod.POST) //注意这个User类的属性应该和data数据的key相同 public UserrequestJsson( @RequestBody User user){ return user; } |
统一异常处理
异常类创建:
1统一异常处理器实现HandlerExceptionResolver接口。
异常处理代码:
2 配置统一异常处理器
3 测试:
拦截器配置
1 实现HandlerInterceptor接口 并重写下面三个方法,
2 配置拦截
总结:
执行preHandle是顺序执行。 (先将所有拦截器的preHandle执行)
执行postHandle、afterCompletion是倒序执行 (然后倒叙执行)
在xml中配置拦截器按顺序向下执行。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 大模型 Token 究竟是啥:图解大模型Token
· 35岁程序员的中年求职记:四次碰壁后的深度反思
· 继承的思维:从思维模式到架构设计的深度解析
· 如何在 .NET 中 使用 ANTLR4
· 后端思维之高并发处理方案
· BotSharp + MCP 三步实现智能体开发
· BotSharp 5.0 MCP:迈向更开放的AI Agent框架
· 5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
· 【ESP32】两种模拟 USB 鼠标的方法
· 设计模式脉络