QuickStart
1. 环境的搭建
- maven–>框架(webApp),在创建过程中,解决项目创建过慢问题,加入一组键值对<archetypeCatalog,internal>
- maven项目的架构一般都是固定的,main下面应该有Java和resources两个目录,Java(make directory as …)x写类,resources(make directory as …)写配置文件
- 在pom 文件中,引入jar包
<!-- 编译版本修改为1.8 -->
<properties>`
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!-- Spring版本锁定 -->
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
- 配置前端控制器。前端 控制器是一个servlet,所以它应该配置在webapp–>WEB-INF–>web.xml文件中
<servlet>
<servlet-name>dispatcherServlet</servlet-name>//dispatcherServlet这个名字可以随便取,只要和下面一致就可以了。
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>//类的名称是固定的DispatcherServlet。只敲一个DispatcherServlet,然后自动导入
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>//'/'表示任何请求都会请过这个servlet
</servlet-mapping>
- 在类路径resources目录下,创建Springmvc.xml文件。(xml configuration file–>spring Config)
- 因为原生的index.jsp,没有指定编码,可能会生成乱码,所以我们将其删除。重新生成一个。多了一个头
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
入门
- 我们在index中写如下的代码:用a标签发送一个相应请求,我们应咏Controller层来响应该请求,于是我们写了一个controller类(helloConreoller),来接收该请求。
<html>
<head>
<title>mvc入门程序</title>
</head>
<body>
<a href="hello">入门程序</a>
</body>
</html>
- 我们应咏Controller层来响应该请求,于是我们写了一个controller类(helloConreoller),来接收该请求。
@Controller
public class HelloController {
@RequestMapping(path=“/hello”)
public String sayhello(){
System.out.println("hello Springmvc");
return "success;
}
}
- @Controller 有了,那么我们怎么让程序识别到它呢?在此之前,我们要用该类的一个方法,应该先将这个类编程一个对象,将该类交给spring 的 io 容器管理。将答案是对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/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
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-4.0.xsd">
<!-- 只扫描带有controller注解的控制器 -->
<context:component-scan base-package="cumt.controller" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
</beans>
- 加载springmvc.xml文件。在web.xml文件的前端控制器中,配置加载。(servlet中)
<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> 加载类路径下的springmvc配置文件
</init-param>
<load-on-startup>1</load-on-startup> //servlet每次创建都会加载springmvc的配置文件
</servlet>
- 配置视图解析器。(return “success”).在WEB-INF下创建pages文件夹(创建seccess.jsp)
<!--视图解析器-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">类名为InternalResourceViewResolver,id无所谓
<property name="prefix" value="/WEB-INF/pages/"/>//路径
<property name="suffix" value=".jsp"/>//后缀
</bean>
- 配合注解框架。(在spingmvc.xml文件中加了这个代码,就相当于配置了,处理器映射器,处理器,处理器适配器等)
<!--开启springmvc框架注解的支持-->
<mvc:annotation-driven/>
注解
@requestMapping
- 作用:用于建立请求URL和 处理 请求方法之间的对应关系
- 出现的位置:类上(一级目录,好处:使代码模块化,更加方便管理)或者方法(二级目录)上。
- 属性:path、value 的作用是一样的。@RequestMapping(path=“/add”),当是有一个属性时,path可写可不写
- . method:指定请求方式。(a标签是get请求)例子:@RequestMapping(path = “/hello”,method = {RequestMethod.POST,RequestMethod.GET})
- . params。params={“username”},请求参数中 必须有一个名字为username的参数
<a href="hello?username=kk">入门程序</a>
params = {"username=gg"}//传入的username的值必须为gg
- headers:用于指定限制请求头的条件,必须要包含这个请求头。,否则请求不到
headers = {"Accept"}
请求参数的绑定
接收零散的属性
<a href="param/info?username=kk">params参数绑定</a>
如果参数比较少的化,后台接受请求参数。这两个名字必须一模一样,写错了,可封装不上!
public String sayinfo(String username){
System.out.println(username);
}
javabean封装
使用javaBean封装。当参数比较多时,可使用这种方法。(JavaBean有两个条件:实现 Serializable 接口 和写Set/get方法)
public class Account implements Serializable {//实现序列化
private String username;
private String password;
private Double money;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", money=" + money +
'}';
}
}
controller
@RequestMapping("/saveAccount")
public String saveAccount(Account account){
System.out.println(account);
return "success";
}
jsp
<form action="param/saveAccount" method="post">
用户名:<input type="text" name="username"/><br/>
密码: <input type="text" name="password"/><br/>
金额: <input type="text" name="money"/><br/>
<input type="submit" value="提交"></input>
</form>
jababean中有引用类型
private User user;
引用类型也同样要满足那两个条件(实现 Serializable 接口 和写Set/get方法)
public class User implements Serializable {
private String uname;
private Integer age;
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"uname='" + uname + '\'' +
", age='" + age + '\'' +
'}';
}
jsp
<form action="param/saveAccount" method="post">
用户名:<input type="text" name="username"/><br/>
密码: <input type="text" name="password"/><br/>
金额: <input type="text" name="money"/><br/>
姓名: <input type="text" name="user.uname"/><br/>
年龄: <input type="text" name="user.age"/><br/>
<input type="submit" value="提交"></input>
</form>
配置解决中文乱码的过滤器
- get不会出现乱码,post会。以前post乱码的解决方式是:request.setChar
- 在web.xml文件中添加如下代码:
<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>
javabean中有集合
private List<User> list;
private Map<String,User> map;
姓名: <input type="text" name="list[0].uname"/><br/>
年龄: <input type="text" name="list[0].age"/><br/>
姓名: <input type="text" name="map['one'].uname"/><br/>
年龄: <input type="text" name="map['one'].age"/><br/>
自定义类型转化器
- 新建一个utils包,创建该类
public class StringToDataConverter implements Converter<String, Date> {
@Override
public Date convert(String s) {
//判斷字符串
if (s == null) {
throw new RuntimeException("空数据内容");
}
DateFormat df = new SimpleDateFormat("yyyy-mm-dd");
try {
return df.parse(s);
} catch (Exception e) {
throw new RuntimeException("格式错误");
}
}
}
- 在springmvc.xml文件中进行配置
<!--配置自定转化器-->
<bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="cumt.controller.utils.StringToDataConverter"/>
</set>
</property>
</bean>
<!--开启springmvc框架注解的支持-->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"/>
常用注解介绍
@requestparam
- 应用场景,请求的参数必须与controller名一样,否则会报错,很难受。
- 有了这个注解后:
public String testRequestParam(@RequestParam(name="name") String username){
<a href="anno/testRequestParam?name=heihei">测试RequestParam</a>
@requestBody
jsp
<form action="anno/testRequestBody" method="post">
姓名:<input type="text" name="username">
密码:<input type="text" name="password">
<input type="submit" value="提交">
</form>
controller
@RequestMapping("testRequestBody")
public String testRequestBody(@RequestBody String body){
System.out.println(body);
return "success";
}
@requestVariable
这是restful风格的书写方式。
@RequestMapping("/testPathVariable/{sid}")
public String testPathVariable(@PathVariable(name = "sid") String id){
System.out.println(id);
return "success";
}
<a href="anno/testPathVariable/10">测试RequestParam</a>//直接写/10,而不用写id=10
由于浏览器表表单值支持GET 与post请求,而delete,put,等method不支持。于是spring增加了一个过滤器,将浏览器请求改为指定的请求方式,发送给我们的控制器方式。于是乎,GWT,POST,PUT,DELETE请求都得到了支持。
@requestHeader获取请求头的值
@CookieValue,获取cookievalue的值
@ModelAttribute
- 可用于修饰方法和参数
- 出现在方法上:表示当前方法会在控制器 方法执行前执行。可以修饰没有返回值的方法,有可以修饰有具体返回值的方法。
- 出现在参数上,获取指定的数据给参数赋值。
<form action="anno/testModelAttribute" method="post">
@RequestMapping("/testModelAttribute")
public String testModelAttribute(){
System.out.println("testModelAttribute方法执行了");
return "success";
}
@ModelAttribute
public void showModelAttribute(){
System.out.println("show方法执行了");
}
show方法执行了
testModelAttribute方法执行了
- 应用场景,表单中提交的数据,少于该类型属性的全部数据,使用此注解,可使其先到数据库中查询获取未填写的数据。
/*表单只提交了两个*/
<form action="anno/testModelAttribute" method="post">
姓名:<input type="text" name="uname">
密码:<input type="text" name="password">
<input type="submit" value="提交">
</form>
/*但其实他有3个属性*/
public class User implements Serializable {
private String uname;
private Integer age;
private Date data;
/*不过没关系,利用注解从数据库中拿*/
@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user){
System.out.println(user);
return "success";
}
@ModelAttribute
public User showModelAttribute(){
//模拟查询数据库
User user= new User();
user.setAge(20);
user.setUname("lisi");
user.setData(new Date());
return user;
}
- 如果该注解注释的方法没有返回值类型,那么可以用一个Map类型,将该注解写在map集合中。然后利用该注解取值。
@ModelAttribute
public void showModelAttribute(String uname, Map<String,User>map){
User user= new User();
user.setAge(20);
user.setUname("lisi");
user.setData(new Date());
map.put("abc",user);
}
@RequestMapping("/testModelAttribute")
public String testModelAttribute(@ModelAttribute("abc") User user){
System.out.println(user);
return "success";
}
@SessionAttribute
用于域之间数据共享
@RequestMapping("/testSessionAttributes")
public String testSessionAttributes (Model model){
model.addAttribute("msg","小美");
return "success";
}
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>//开启EL注解
<html>
<head>
<title>Title</title>
</head>
<body>
<h4>success!</h4>
${requestScope}
@RequestMapping("/testSessionAttributes")
public String testSessionAttributes (Model model){
model.addAttribute("msg","小美");
return "success";
}