执行原理
简单程序
先配置web.xml 配置前端解析器DispatchetServlet
<web-app>
<display-name>Archetype Created Web Application</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:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
配置mvc配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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
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
">
<context:component-scan base-package="com.csc.controller"/><!--扫描注解-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/><!--视图解析器增加前后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
编写controller
package com.csc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
@RequestMapping("/hello")
public String hello()
{
System.out.println(5646546);
return "/succ.jsp";
}
}
@RequestMapping
建立URL与处理方法之间的对应关系
可以作用在方法和类上
作用在类上为一级路径
作用在方法上为二级路径
属性
path 请求路径
value 请求路径
parpms 指定限制请求路径上参数
method 请求方式 POST GET
例如:
@RequestMapping(path = "/add",params = {"username"},method = {RequestMethod.GET})
public String addUser(String username,Integer age)
{
System.out.println("姓名" + username);
System.out.println("年龄:"+age);
return "succ";
}
提交参数中必须含有username,提交类型必须是get
请求参数
普通类型
form表单中name自动与controller方法中的参数名字一直就会自动接收
例如
<form action="/user/add" METHOD="get">
姓名:<input type="text" name="username" >
年龄:<input type="text" name="age">
<input type="submit" value="提交">
</form>
@RequestMapping(path = "/add",params = {"username"},method = {RequestMethod.GET})
public String addUser(String username,Integer age)
{
System.out.println("姓名" + username);
System.out.println("年龄:"+age);
return "succ";
}
form中的username与addUser中参数一致可以接收
绑定到对象类型中
- 新建对象User 对象中含有引用对象及List集合
public class User implements Serializable {
private String username;
private Integer age;
private Address address;
private List<Address> list;
- form表单填写规则
<form action="/user/adduser" METHOD="get">
姓名:<input type="text" name="username" >
年龄:<input type="text" name="age">
地址:<input type="text" name="address.country">
<input type="text" name="address.money">
地址集合:<input type="text" name="list[0].country">
<input type="text" name="list[0].money">
<input type="submit" value="提交">
</form>
引用对象的name使用address.country
list集合使用下标.属性 从0开始
3. 查看输出
@RequestMapping("/adduser")
public String addUser(User user)
{
System.out.println(user);
return "succ";
}
User{username='aaa', age=12, address=Address{country='DDDD', money=121.66}, list=[Address{country='EEEEE', money=131.11}]}
解决中文乱码
在web.xml中配置过滤器可以防止表单post方式提交时的中文乱码
get不会产生乱码 tomcat8解决此问题
<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>
@DateTimeFormat日期格式类型转换
表单提交类型转换成Data类型
@DateTimeFormat(pattern = "yyyy-mm-dd")
private Date birthday;
提交后会自动转化 但是其他格式不会转换 默认格式2020/01/01
自定义类型转换器
- 编写自定义类型转换器
public class StringToDate implements Converter<String, Date> {
@Override
public Date convert(String s) {
if(s!=null)
{
SimpleDateFormat ss = new SimpleDateFormat("yyyy-MM-dd");
Date parse = null;
try {
parse = ss.parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
return parse;
}
return null;
}
}
- 编写配置文件
<bean name="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters" >
<set>
<!--把自己新建的转换器放到工厂里-->
<bean class="com.csc.until.StringToDate"></bean>
</set>
</property>
</bean>
<!--加到注解驱动中-->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"/>
- 使用转化器
使用servlet原生的API接收参数
@RequestMapping("/adduser")
public String addUser1(HttpServletRequest req, HttpServletResponse resp)
{
HttpSession session = req.getSession();
String username = req.getParameter("username");
return "succ";
}
@RequestParam
作用在方法参数列表里,作用:当表单提交的name与接收参数名字不一致时可以使用
@RequestMapping("/addUser2")
public String addUser2(@RequestParam(value = "name",required = false,defaultValue = "mmyc") String username)
{
System.out.println(username);
return "succ";
}
value 接收的input里的name放到username里,
required 是否必须 ,当为true 时如果input没有name会报错,
defaultValue 默认值
@RequestBody
作用在方法参数列表里,作用:接收ajax异步请求,将接收的信息转换成字符串对象,只能接收post请求
@RequestMapping("/adduser3")
public String addUser3(@RequestBody String name)
{
System.out.println(name);
return "succ";
}
@PathVariable
作用在方法参数列表里,作用:restful风格传参 接收请求路径里的参数放到方法列表里
@RequestMapping(method = RequestMethod.POST)
public String addUset()
{
return "succ";
}
@RequestMapping(value = "/find",method = RequestMethod.GET)
public String getAll()
{
return "succ";
}
@RequestMapping(value = "/find/{id}",method = RequestMethod.GET)
public String getOne(@PathVariable(value ="id") long username)
{
System.out.println(id);
return "succ";
}
value = “/find/{id}” 路径fing下有下一级即可 没必要名字一直 PathVariable取到路径上的id放到参数username中
@RequestHeader @CookieValue
作用在方法参数列表里,作用:用于获取请求头信息,与cookie信息
@RequestMapping(value = "/find",method = RequestMethod.GET)
public String getAll(@RequestHeader(value = "Accept ") String str, @CookieValue(value ="JSESSIONID" ) String sessionID)
{
System.out.println("str");
System.out.println(sessionID);
return "succ";
}
获取请求头的Accept 与cookie中的Sesion的id
Controller返回值void
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/add")
public void addUser(User u)
{
System.out.println(u);
}
}
访问addUser方法时,默认返回的是/user/add路径 与请求路径一致
可以设置原生的servletAPI进行请求转发
@RequestMapping("/add")
public void addUser(HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
request.getRequestDispatcher("/pages/succ.jsp").forward(request,response);
}
此处地址得写全路径,InternalResourceViewResolver不能进行加路径操作。
请求转发与重定向
@RequestMapping("/add1")
public String addUse1r() {
return "forward:/pages/succ.jsp";
}
@RequestMapping("/add2")
public String addUse3r() {
return "redirect:/pages/succ.jsp";
}
也必须写全路径
@ResponseBody
@RequestMapping("/save")
public @ResponseBody User saveUser(@RequestBody User user)
{
System.out.println(user);
user.setUsername("AAA");
return user;
}
文件上传与下载
导入依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.7</version>
</dependency>
在spring配置文件中配置bean
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
id必须为multipartResolver
编写jsp提交表单
<form action="/user/upload" method="post" enctype="multipart/form-data">
上传文件 <input type="file" name="multipartFile">
<input type="submit" value="上传">
</form>
上传代码
@RequestMapping("/upload")
public String upload(MultipartFile multipartFile,HttpServletRequest request) throws IOException {
//创建上传的位置
String realPath = request.getSession().getServletContext().getRealPath("/upload");
File file = new File(realPath);
if(!file.exists())
{
file.mkdir();
}
//获取文件名字
String fileName=multipartFile.getOriginalFilename();
String replace = UUID.randomUUID().toString().replace("-", "");
fileName=replace+fileName;
//上传文件
multipartFile.transferTo(new File(file,fileName));
return "succ";
}
注意:上传表单中的input里name要与方法中 upload(MultipartFile multipartFile,HttpServletRequest request) 参数名字一直 不一致没法接收。也可以使用public @ResponseBody ComResponse fileUpload( @RequestParam(“uploadFile”) MultipartFile uploadFile,HttpServletRequest httpServletRequest) {
起别名接受。
异常处理 HandlerExceptionResolver
java代码需要实现HandlerExceptionResolver并且加注解@Compont交给容器管理
@Component("myExceptionResovler")
public class MyExceptionResovler implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
e.printStackTrace();//控制台打印异常
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("errorMsg",e.getMessage());
modelAndView.setViewName("error");
return modelAndView;
}
}
然后出现异常时会自动调用此方法然后跳转到error.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>${errorMsg}</h3>
</body>
isELIgnored 忽略EL表达式
拦截器 HandlerInterceptor
需要实现HandlerInterceptor
java代码
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("方法执行前");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("controller方法return之前执行");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("方法执行后");
}
}
使用配置
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/user/interceptor"/><!--拦截地址-->
<bean id="interceptor" class="com.csc.interceptor.MyInterceptor"></bean><!--拦截器-->
</mvc:interceptor>
</mvc:interceptors>