首页 > 代码库 > SpringMVC学习资料
SpringMVC学习资料
一、SpringMVC
1、helloworld
1、导包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>
2、在web.xml中配置
<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:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
3、在springmvc.xml 中
<context:component-scan base-package="com.ibc.test"></context:component-scan>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="http://www.mamicode.com/WEB-INF/"></property>
<property name="suffix" value="http://www.mamicode.com/.jsp"></property>
</bean>
4、定义一个类用@Controller修饰,表示自动被扫描
定义一个带String返回值的方法
用@RequestMapping("/helloworld") 修饰 表示url地址
@Controller
public class HelloWorld {
@RequestMapping("/helloworld")
public String sayHello(){
System.out.println("Hello MVC");
return "success";
}
}
[访问用helloworld.do] 返回页面 prefix+"success"+ suffix 做转发操作
5、index.jsp
<a href="http://www.mamicode.com/helloworld">helloworld</a>
2、RequestMapping
1、可以修饰方法,修饰类
url地址 = 修饰类的/修饰方法的
类上的路径默认是 /
方法是相对于类路径的。
value url 地址
2、提交方式
主要分为get,post
RequestMethod.POST 或者 RequestMethod.GET
例如:
@RequestMapping(value="http://www.mamicode.com/helloworld",method=RequestMethod.POST)
3、请求参数,请求头 了解
精确映射请求。
params 、heads
支持简单表达式
param1 表示请求必须包含这个参数
!param1 表示请求不能包含这个参数
param1=value1 表示包含这个参数,并且这个参数值必须为value1
param1!=value1 表示包含这个参数,并且这个参数不能为value1
可以是一个数组
{"param1=value1","param2"} 请求必须包含参数param1和param2
的两个请求参数,切param1参数的值必须为value1
例如:
@RequestMapping(value="http://www.mamicode.com/helloworld",method=RequestMethod.GET,
params={"username","age!=10"},headers={"Accept-Language=zh-CN,zh;q=0.8"})
4、ant风格的url
? 任意一个字符
* 任意个字符
** 多层路径
例如:
@RequestMapping(value="http://www.mamicode.com/user/**/helloworld")
表示跟路径下,user文件夹下,任意子文件夹,含有helloworld路径的url地址。
5、@PathVariable 注解
在url中可以使用占位符 {id}
作用:映射url中的占位符到目标方法的参数中。
如:@RequestMapping("/delete/{id}")
在方法参数中写@PathVariable("id") 注解修饰参数。
如:
@RequestMapping("/delete/{id}")
public String delete(@PathVariable("id") Integer id){
UserDao.delete(id);
return "redirect:/user/list.action"
}
6、REST
资源表现层转化
实例:
/order/1 HTTP GET : 得到 id=1 的order get?id=1
/order/1 HTTP DELETE : 删除 id=1 的order
/order/1 HTTP PUT : 更新 id=1 的order
/order HTTP POST : 新建 一个 order
HiddenHttpMethodFilter 这个过滤器会把post转换为put和delete请求。
1、tomcat需要在7以下版本测试,8及以上不好用。
2、在web.xml中配置HiddenHttpMethodFilter 过滤器
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3、在Action中书写四种不同的控制方法
通过@PathVariable 来获取id
@RequestMapping(value="http://www.mamicode.com/testRest/{id}",method=RequestMethod.GET)
public String testRest(@PathVariable Integer id){
System.out.println("get "+id);
return "success";
}
@RequestMapping(value="http://www.mamicode.com/testRest",method=RequestMethod.POST)
public String testRest(){
System.out.println("post ");
return "success";
}
@RequestMapping(value="http://www.mamicode.com/testRest/{id}",method=RequestMethod.DELETE)
public String testRestDelete(@PathVariable Integer id){
System.out.println("DELETE "+id);
return "success";
}
@RequestMapping(value="http://www.mamicode.com/testRest/{id}",method=RequestMethod.PUT)
public String testRestPut(@PathVariable Integer id){
System.out.println("PUT "+id);
return "success";
}
4、在JSP中写相关测试代码
<a href="http://www.mamicode.com/testRest/1">helloworld</a> //get
<br><br>
<form action="testRest" method="post"> //post
<input type="submit" value="http://www.mamicode.com/post">
</form>
<br><br>
<form action="testRest/1" method="post"> //delete
<input type="hidden" name="_method" value="http://www.mamicode.com/DELETE">
<input type="submit" value="http://www.mamicode.com/DELETE">
</form>
<br><br>
<form action="testRest/1" method="post"> //put
<input type="hidden" name="_method" value="http://www.mamicode.com/PUT">
<input type="submit" value="http://www.mamicode.com/put">
</form>
<br><br>
7、@RequestParam
绑定请求参数
1、写一个Action
@RequestMapping("/testRequestParam")
public String testRequestParam(@RequestParam(value="http://www.mamicode.com/username") String uname,@RequestParam("pass") Integer pass){
System.out.println(uname+" "+pass);
return "success";
}
2、写一个测试JSP
<a href="http://www.mamicode.com/testRequestParam?username=tom&pass=123">testRequestParam</a>
3、@RequestParam(value="http://www.mamicode.com/pass",required=false,defaultValue="http://www.mamicode.com/0") Integer age
其中required默认是true 表示必须有,false表示可以没有。
age最好是Integer,如果是int最好设默认值。
defaultValue 表示默认值。
8、@RequestHeader
表示获取请求的头信息
1、写一个Action
@RequestMapping("/testRequestHeader")
public String testRequestHeader(@RequestHeader("Accept-Language") String header){
System.out.println("testRequestHeader "+header);
return "success";
}
2、写一个jsp
<a href="http://www.mamicode.com/testRequestHeader">testRequestHeader</a>
9、@CookieValue
表示获取cookie信息
1、写一个Action
@RequestMapping("/testRequestCookie")
public String testRequestCookie(@CookieValue("JSESSIONID") String sessionid){
System.out.println("sessionid" +sessionid);
return "success";
}
2、写一个jsp
<a href="http://www.mamicode.com/testRequestCookie">testRequestCookie</a>
10、使用POJO做参数
自动匹配
1、写一个Action
@RequestMapping("/testStudent")
public String testStudent(Student stu){
System.out.println(stu);
return "success";
}
2、写一个jsp
<a href="http://www.mamicode.com/testStudent?stuid=111&stuname=jack&age=23&address.province=liaoning&address.city=shenyang">testStudent</a>
11、使用原生的request、response作为参数
springmvc支持的原生api
HttpServletRequest,HttpServletResponse,HttpSession
java.security.Principal
Locale
InputStream,OutputStream
Reader,Writer
1、定义一个Action,附带中文处理
@RequestMapping("/testServletApi")
public void testServletApi(HttpServletRequest request,HttpServletResponse response,OutputStream out) throws Exception{
System.out.println(request +" "+response);
OutputStreamWriter osw=new OutputStreamWriter(out,"GBK");
BufferedWriter bw=new BufferedWriter(osw);
bw.write("你好! 是mi");
bw.newLine();
bw.flush();
bw.close();
}
2、定义一个jsp调用
<a href="http://www.mamicode.com/testServletApi">testServletApi</a>
12、ModelAndView
springMVC会把ModelAndView里的数据放入到request域对象里面
1、定义一个Action
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
ModelAndView ret =new ModelAndView("success");
ret.addObject("time", new Date());
return ret;
}
2、 定义一个JSP
<a href="http://www.mamicode.com/testModelAndView">testModelAndView</a>
3、定义success.jsp
在jsp指令元素中添加属性 isELIgnored="false"
${requestScope.time}
13、Map参数
处理模型数据的,数据放入request范围内。也可以是ModelMap、Model类型,
类似于ModelAndView
1、定义一个Action
@RequestMapping("/testMap")
public String testMap(Map map,Model model,ModelMap mmap){
model.addAttribute("age", 23);
mmap.put("address", "beijing");
map.put("name", "tttom");
return "success";
}
2、定义一个jsp
<a href="http://www.mamicode.com/testMap">testMap</a>
3、修改success.jsp
在jsp指令元素中添加属性 isELIgnored="false"
${requestScope.name} ${requestScope.age} ${requestScope.address}
这里注意,map作为参数的主要作用是为了响应页面收集收据!!!
14、@SessionAttirbute
***只能放在类上面
表示那些属性放入session中
@SessionAttributes(value=http://www.mamicode.com/{"stus"},types={String.class})
可以通过名字放入,也可以通过类型放入。同时写是或者的关系。
1、定义一个Action
类部分
@SessionAttributes({"stus"})
@Controller
public class HelloWorld {
方法部分
@RequestMapping("/testSessionAttribute")
public String testSessionAttribute(Map map){
Student stu=new Student(11, "tom", 21);
map.put("stus", stu);
return "success";
}
2、定义一个jsp
<a href="http://www.mamicode.com/testSessionAttribute">testSessionAttribute</a>
3、修改success.jsp
在jsp指令元素中添加属性 isELIgnored="false"
${requestScope.stus} ${sessionScope.stus}
两个范围都有数据。
15、@ModelAttribute
*** 模拟拦截器功能
会在目标方法执行之前执行。
1、写一个Action
@ModelAttribute
public void getStu(@RequestParam(value = "http://www.mamicode.com/stuid", required = false) Integer stuid,Map<String,Object> map) {
if (stuid != null) {
Student stu = new Student(1, "jack", 23);
System.out.println(stu);
map.put("student", stu);
}
System.out.println("getStu");
}
业务方法
@RequestMapping("/testModelAttribute")
public String testModelAttribute(Student stu) {
System.out.println(stu);
return "success";
}
***这里注意:map.put("student", stu); key值是 方法参数的类型
2、写一个JSP
<form action="testModelAttribute" method="post">
<input type="hidden" name="stuid" value="http://www.mamicode.com/1" >
username :<input type="text" name="stuname" value="http://www.mamicode.com/Tom"> <br>
<!-- age : <input type="text" name="age" value="http://www.mamicode.com/23"><br> -->
<input type="submit">
</form>
-------------第二种用法
1、写一个Action
@ModelAttribute
public void getStu(@RequestParam(value = "http://www.mamicode.com/stuid", required = false) Integer stuid,Map<String,Object> map) {
if (stuid != null) {
Student stu = new Student(1, "jack", 23);
System.out.println(stu);
map.put("abc", stu);
}
System.out.println("getStu");
}
业务方法
@RequestMapping("/testModelAttribute")
public String testModelAttribute(@ModelAttribute("abc") Student stu) {
System.out.println(stu);
return "success";
}
注意: 这里map中的key值不是student了,改成了abc,只需在业务的方法中对参数做@ModelAttribute("abc")
注解修饰也可。
abc 就是key值
16、SpringMVC 确定POJO类型入参过程
1、确定一个key
1.1、若目标方法的POJO类型的参数没有使用@ModelAttribute作为修饰,则key为POJO类名首字母小写,
1.2、若使用了@ModelAttribute来修饰,则key为@ModelAttribute注解的value属性值
2、在implicitModel中查找key对应的对象,若存在,则作为入参传入
3、若implicitModel中不存在key对应的对象,则检查档案的Handler是否使用@SessionAttirbute注解修饰,
若使用了该注解,且@SessionAttirbute注解的value属性值包含了key,则会从HttpSession中来获取key所
对应的value值,若存在则直接传入到目标方法的入参中,若不存在则抛出异常。
4、若Handler没有标识@SessionAttirbute注解或@SessionAttirbute注解的value值中不包含key,则
会通过反射来创建POJO类型的参数,传入为目标的方法
5、SpringMVC 会把key和value保存到implicitModel中,进而会保存到request中。
17、@SessionAttirbute 注解引发的异常
如果类上有
@SessionAttributes(value=http://www.mamicode.com/{"student"},types={String.class})
@Controller
public class HelloWorld {
只有
@RequestMapping("/testModelAttribute")
public String testModelAttribute( Student stu) {
System.out.println(stu);
return "success";
}
没有
@ModelAttribute
public void getStu(@RequestParam(value = "http://www.mamicode.com/stuid", required = false) Integer stuid,Map<String,Object> map) {
if (stuid != null) {
Student stu = new Student(1, "jack", 23);
System.out.println(stu);
map.put("student", stu);
}
System.out.println("getStu");
}
会报错,应为是先从session中取"student" 数据,没有报错,如果加上 @ModelAttribute
就可以了,它会先放入session中,再取出来。
3、视图和试图解析器
所有返回的类型,最终都被转换为ModelAndView ,通过视图解析器,得到最用的View视图。
1、<mvc:view-controller path="/success" view-name="success"/>
这个标签是通过url直接进入jsp页面,不通过Control。
注意:一旦这么配置后,success只能走url到jsp了,其他从url到control到jps都不好用了,
解决方案
增加一个标签 <mvc:annotation-driven></mvc:annotation-driven>,就都好用了
2、自定义视图
1、首先在springmvc.xml配置文件中添加
<!-- 使用view name 来解析视图 -->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="http://www.mamicode.com/100"></property>
</bean>
order小的排在前面解析,默认是int的最大值。
2、写一个自定义的View
@Component
public class HelloView implements View {
public String getContentType() {
return "text/html";
}
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
throws Exception {
response.getWriter().println("hello hello tom jack");
}
}
其中,这个类一定要被IOC管理,所以写 @Component
getContentType 这个方法返回的是响应页面的mime类型。
render 制作文件内容。
3、 测试
1、写一个Action
@RequestMapping("/testView")
public String testView(){
return "helloView";
}
2、写JSP
<a href="http://www.mamicode.com/testView">testView</a>
3、重定向或者转向
返回的字符串中 如果以forward:开始表示转向
返回的字符串中 如果以redirect:开始表示重定向
默认转向。
1、写一个Action
@RequestMapping("/testRedirect")
public String testRedirect(){
return "redirect:/success";
}
2、写一个JSP
<a href="http://www.mamicode.com/testRedirect">testRedirect</a>
4、REST风格项目注意
1、springMVC 本身没有导入JSTL,需要手动导入
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
2、 jsp中倒入标签
1、jstl标签导入
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
2、springMVC 标签导入
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
针对form表单,必须在共享范围内具有对应的JavaBean
所以在Control类中,需要写一个
@ModelAttribute
public void init(Map<String,Object> map){
map.put("student", new Student());
}
预先放入JavaBean。
3、目前只能访问Control,而普通的访问不了。 **处理静态资源方法
在springmvc.xml的配置文件中,添加
不影响正常的jsp访问
<mvc:default-servlet-handler/>
不影响正常的servlet访问,servlet没映射的用servlet默认处理
<mvc:annotation-driven></mvc:annotation-driven>
4、编辑时,不能使用url尽量使用绝对路径
5、编辑时,回显数据,不要用 <form:hidden path="_method" value="http://www.mamicode.com/POST"/>
而需要使用 <input type="hidden" name="_method" value="http://www.mamicode.com/POST">
3、 / 和 /* 的区别
/ 过滤Control
/* 过滤所有url访问
4、类型解析器
1、自定义类型转换器
把一个String转换为Student对象
1、编写一个转换器类,实现org.springframework.core.convert.converter.Converter 这个接口
这个类要被IOC管理
public class StringToStudent implements Converter<String, Student>{
public Student convert(String arg0) {
Student ret=null;
if(arg0!=null){
String str[]=arg0.split("-");
if(str.length==3){
ret=new Student(33,str[0],Integer.parseInt(str[1]),str[2]);
System.out.println(ret);
}
}
return ret;
}
}
2、配置这个类到springMVC中 ,修改文件 springmvc.xml
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.ibc.student.tools.StringToStudent"></bean>
</set>
</property>
</bean>
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<mvc:default-servlet-handler/>
3、写一个JSP
<a href="http://www.mamicode.com/addStudent?student=tom-23-tianjin">查询addStudent</a> <br>
2、 annotation-driven
通常都需要加入这个配置。
3、@InitBinder
对WEbDataBinder对象初始化,
主要用于表单字段到JavaBean的绑定。
要求 @InitBinder 方法不能有返回值
@InitBinder 方法的参数,通常是WebDataBinder
如:
@InitBinder
public void initBinder(WebDataBinder binder){
// 表示在String到Student转换过程中,哪些属性不赋值
binder.setDisallowedFields("address");
}
1、写一个Action
@InitBinder
public void initBinder(WebDataBinder binder){
System.out.println("initBinder");
binder.setDisallowedFields("address");
}
@RequestMapping(value="http://www.mamicode.com/addOne",method=RequestMethod.POST)
public String addOne(Student stu,Map<String,Object> map){
map.put("studs", iStudentService.addOne(stu));
return "studentList";
}
2、写一个JSP
<form action="addOne" method="post">
sname:<input type="text" name="sname"><br>
sage:<input type="text" name="sage"><br>
address:<input type="text" name="address"><br>
<input type="submit" value="http://www.mamicode.com/POST">
</form>
注意:操作要点
1、必须是表单自动转换JavaBean
4、数据格式化
string转换为Date
1、在配置文件里面必须有
<mvc:annotation-driven ></mvc:annotation-driven> 只能这样。
2、在实体类中对应的属性添加注解
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birthday;
3、写一个Action文件
@RequestMapping(value="http://www.mamicode.com/addOne",method=RequestMethod.POST)
public String addOne(Student stu,Map<String,Object> map){
map.put("studs", iStudentService.addOne(stu));
return "studentList";
}
4、写一个JSP文件
<form action="addOne" method="post">
sname:<input type="text" name="sname"><br>
sage:<input type="text" name="sage"><br>
address:<input type="text" name="address"><br>
birthday:<input type="text" name="birthday"><br>
<input type="submit" value="http://www.mamicode.com/POST">
</form>
其中birthday 部分输入2000-3-4 进行验证。
string转换为float
1、同上
2、
@NumberFormat(pattern="###,###,###.##")
private Float salary;
3、4
注意:
如果即想要数据格式化有想用自己的类型转换器好用。
1、修改配置文件
<mvc:annotation-driven conversion-service="conversionService" ></mvc:annotation-driven>
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.ibc.student.tools.StringToStudent"></bean>
</set>
</property>
</bean>
注意:类型改变了,变为FormattingConversionServiceFactoryBean
5、 类型转换错误
1、需要Action中添加参数
@RequestMapping(value="http://www.mamicode.com/addOne",method=RequestMethod.POST)
public String addOne(Student stu,BindingResult result,Map<String,Object> map){
System.out.println("-------addOne-------");
if(result.getErrorCount()>0){
for (FieldError error : result.getFieldErrors()) {
System.out.println(error.getObjectName()+" "+error.getDefaultMessage());
}
}
map.put("studs", iStudentService.addOne(stu));
return "studentList";
}
*****特别注意:Student stu,BindingResult result 这两个参数必须挨着
6、数据校验
1、添加jar包
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>6.0.0.Alpha1</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.6</version>
</dependency>
注意,这里面el-api 可能会与tomcat中的jar包冲突。
2、在实体类的属性上修饰
@NotEmpty
private String sname;
3、在Control上的方法属性做修饰
@RequestMapping(value="http://www.mamicode.com/addOne",method=RequestMethod.POST)
public String addOne(@Valid Student stu,BindingResult result,Map<String,Object> map){
注意
@Valid Student stu,BindingResult result 挨着
4、出错去的页面
@ModelAttribute
public void init(Map<String,Object> map){
map.put("student", new Student());
}
@RequestMapping(value="http://www.mamicode.com/addOne",method=RequestMethod.POST)
public String addOne(@Valid Student stu,Errors result,Map<String,Object> map){
map.put("student", stu);
if(result.getErrorCount()>0){
for (FieldError error : result.getFieldErrors()) {
System.out.println(error.getObjectName()+" "+error.getDefaultMessage());
}
return "index";
}
return "redirect:/searchAll";
}
5、在错误页面
<form:form action="addOne" method="post" modelAttribute="student">
<form:errors path="*"></form:errors>
<br>
sname:<form:input path="sname"/><form:errors path="sname"></form:errors><br>
address:<form:input path="address"/><br>
sage:<form:input path="sage"/><br>
birthday:<form:input path="birthday"/><form:errors path="birthday"></form:errors><br>
salary:<form:input path="salary"/><form:errors path="salary"></form:errors><br>
<form:button >tijiao</form:button>
</form:form>
注意:<form:errors path="*"></form:errors> 一定要放在<form:form action="addOne" method="post" modelAttribute="student">中。
path可以是属性名,也可以是* ,*代表全部
7、国际化
1、编写一个属性文件叫i8n.property
NotEmpty.student.sname=sname \u4E0D\u80FD\u4E3A\u7A7A\uFF01
注意,NotEmpty 表示注解类名
student 是实体类在IOC中的名字
sname 是类的属性名
2、配置国际化文件,在spring的配置文件中
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="http://www.mamicode.com/i18n"></property>
</bean>
3、_en _zh_CN 不好用
8、返回JSON数据
1、引入jar包
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0.pr2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0.pr2</version>
</dependency>
2、写一个Action
@ResponseBody
@RequestMapping("/testJSON")
public List<Student> testJSON(){
return iStudentService.findAll();
}
3、写一个JSP
<script type="text/javascript" src="http://www.mamicode.com/js/jquery-3.2.1.min.js"></script>
<script type="text/javascript">
$(function(){
$("#testjson").click(function(){
var url=this.href;
var args={};
$.post(url,args,function(data){
var str="";
for(var i=0;i<data.length;i++){
var sid=data[i].sid;
var sname=data[i].sname;
var sage=data[i].sage;
var address=data[i].address;
var salary=data[i].salary;
var birthday=data[i].birthday;
str+=sid +"\t"+sname+"\t"+sage+"\t"+address+"\t"+salary+"\t"+birthday+"\n";
}
alert(str);
});
return false;
});
})()
</script>
<a href="http://www.mamicode.com/testJSON" id="testjson">testJSON</a>
4、文件上传
1、写一个JSP
<form action="testUpload" method="post" enctype="multipart/form-data" >
file:<input type="file" name="file"><br>
desc:<input type="text" name="desc"><br>
<input type="submit">
</form>
2、写一个Action
@ResponseBody
@RequestMapping("/testUpload")
public String testUpload(@RequestBody String body){
System.out.println(body);
return "hello hahaha"+new Date();
}
注意:
@RequestBody String body 表示输入参数
里面有表单的所有数据
@ResponseBody
表示响应内容
自动识别类型。例子中响应一个网页字符串。
5、文件下载
1、准备一个文件
download/message.txt
2、写一个Action
@RequestMapping("/testDownLoad")
public ResponseEntity<byte[]> testDownLoad(HttpSession session) throws Exception{
//获取文件byte[]
ServletContext context = session.getServletContext();
InputStream is = context.getResourceAsStream("/download/message.txt");
byte[] body=new byte[is.available()];
is.read(body);
//下载头文件
HttpHeaders headers=new HttpHeaders();
headers.add("Content-Disposition", "attachment;filename=abc.txt");
//获取http状态
HttpStatus statusCode=HttpStatus.OK;
//利用ResponseEntity 实现下载
ResponseEntity<byte[]> ret=new ResponseEntity(body, headers, statusCode);
return ret;
}
3、写一个JSP
<a href="http://www.mamicode.com/testDownLoad" >testDownLoad</a>
6、国际化
1、页面依据浏览器语言设置,对页面文本、时间、数值进行本地化处理。
使用JSTL的fmt标签就可
1、在配置文件中,添加
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="http://www.mamicode.com/i18n"></property>
</bean>
2、写两个属性文件
i18n_en_US.properties
i18n.user=User
i18n.password=Password
i18n_zh_CN.properties
i18n.user=\u7528\u6237\u540D
i18n.password=\u5BC6\u7801
3、写一个JSP文件
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<form action="testGjh" method="post">
<fmt:message key="i18n.user"></fmt:message> <input type="text" name="user"><br>
<fmt:message key="i18n.password"></fmt:message> <input type="text" name="password"><br>
<input type="submit">
</form>
4、验证
用ie浏览器,通过改变语言设置,看变化
工具--》Internate选项--》语言
2、可以在Bean中,获取Locale对应的消息
注入对应的实例就可。
在第一步的基础上,
写一个Aciton
1、属性注入国际化资源
@Autowired
private ResourceBundleMessageSource messageSource;
2、在Action中
@RequestMapping("/testGjh")
public String testGjh(Locale locale){
System.out.println(messageSource.getMessage("i18n.user", null, locale));
return "gjh";
}
注意,可以接参数。locale 作为参数传递过来。
3、可以通过超链接,切换Locale,不依赖浏览器设置
配置LocalResoler和LocaleChangeIntercepteor
1、在配置文件中添加配置
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
</mvc:interceptors>
2、在JSP中
<a href="http://www.mamicode.com/testGjh?locale=zh_CN">中文</a>
<a href="http://www.mamicode.com/testGjh?locale=en_US">英文</a>
注意,传递一个参数locale即可。
7、文件上传
1、添加jar包
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
2、写一个JSP
<form action="testUpload2" method="post" enctype="multipart/form-data" >
file:<input type="file" name="file"><br>
desc:<input type="text" name="desc"><br>
<input type="submit">
</form>
3、写一个Action
@RequestMapping("/testUpload2")
public String testUpload2(@RequestParam("desc") String desc,@RequestParam("file") MultipartFile file,HttpSession session) throws Exception{
InputStream is = file.getInputStream();
FileOutputStream fos=new FileOutputStream(session.getServletContext().getRealPath("download")+"/"+file.getOriginalFilename());
FileCopyUtils.copy(is, fos);
return "index";
}
注意:
1、页面中file的类型为MultipartFile
2、获取输入流
InputStream is = file.getInputStream();
3、获取输出流
FileOutputStream fos=new FileOutputStream(session.getServletContext().getRealPath("download")+"/"+file.getOriginalFilename());
4、 利用工具类实现copy
FileCopyUtils.copy(is, fos);
8、拦截器
1、自定义拦截器 helloworld
1、写一个拦截器类
public class FirstInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("FirstInterceptor preHandle");
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("FirstInterceptor postHandle");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("FirstInterceptor afterCompletion");
}
}
注意:
1、preHandle这个方法是第一个被调用的,如果返回false,下面两个方法不调用了,
如果返回true,下面两个方法被调用
做权限处理
2、postHandle,这个方法是在调用目标方法之后,页面显示之前调用。
往request里面放数据
3、afterCompletion ,这个方法是在显示页面之后调用。
释放资源
2、配置拦截器
在配置文件里面,添加拦截器
<mvc:interceptors>
<bean class="com.ibc.student.interceptor.FirstInterceptor"></bean>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
</mvc:interceptors>
3、指定拦截或者不拦截的设定
指定拦截
<mvc:interceptors>
<bean class="com.ibc.student.interceptor.FirstInterceptor"></bean>
<mvc:interceptor>
<mvc:mapping path="/addOne"/>
<bean class="com.ibc.student.interceptor.SecondInterceptor"></bean>
</mvc:interceptor>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
</mvc:interceptors>
SecondInterceptor 只拦截/addOne 路径 ,其他不拦截,
或者配置,哪些不拦截,其他拦截 <mvc:exclude-mapping path="/testGjh"/>
<mvc:interceptors>
<bean class="com.ibc.student.interceptor.FirstInterceptor"></bean>
<mvc:interceptor>
<mvc:exclude-mapping path="/testGjh"/>
<bean class="com.ibc.student.interceptor.SecondInterceptor"></bean>
</mvc:interceptor>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
</mvc:interceptors>
9、异常处理
1、在配置文件添加
<mvc:annotation-driven ></mvc:annotation-driven>
2、写一个测试的JSP
<a href="http://www.mamicode.com/testException?i=0">testException</a>
3、定义一个错误JSP,error.jsp
4、在action中定义
业务方法
@RequestMapping("/testException")
public String testException(@RequestParam("i") Integer i){
System.out.println("num="+(10/i));
return "index";
}
错误处理方法
@ExceptionHandler(value=http://www.mamicode.com/{ArithmeticException.class})
public String goError(Exception ex){
System.out.println(ex);
return "error";
}
注意:
1、@ExceptionHandler(value=http://www.mamicode.com/{ArithmeticException.class})
value是接受的异常类型数组。
2、方法中,不能接map类型的参数。如果想向error页面传递数据,要用ModelAndView
把第四步改写
@ExceptionHandler(value=http://www.mamicode.com/{ArithmeticException.class})
public ModelAndView goError(Exception ex){
ModelAndView ret =new ModelAndView("error");
ret.addObject("exception", ex);
System.out.println(ex);
return ret;
}
修改错误页面
添加isELIgnored="false" 属性
添加 ${exception } 内容
4、设置全局exception
写一个类,用@ControllerAdvice修饰类,
做全局处理,
处理异常顺序,先自己的,自己的找不到,找@ControllerAdvice 修饰的。
如:
@ControllerAdvice
public class HandleException {
@ExceptionHandler(value=http://www.mamicode.com/{ArithmeticException.class})
public ModelAndView goError(Exception ex){
ModelAndView ret =new ModelAndView("error");
ret.addObject("exception", ex);
System.out.println(ex);
return ret;
}
}
10、定制异常状态码和内容
1、写一个自定义异常,设置异常码和错误信息
@ResponseStatus(value=http://www.mamicode.com/HttpStatus.FORBIDDEN,reason="我的错误")
public class MyException extends RuntimeException {
private static final long serialVersionUID = 1L;
}
2、写一个JSP
<a href="http://www.mamicode.com/testHttpStatus?i=0">testHttpStatus?i=0</a>
3、写一个Action
@RequestMapping("/testHttpStatus")
public String testHttpStatus(@RequestParam("i") Integer i){
if(i==0){
throw new MyException();
}
return "index";
}
11、配置异常,指定异常到指定页面
1、写配置文件,表示页面出现java.lang.ArrayIndexOutOfBoundsException 自动进入error.jsp页面
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop>
</props>
</property>
</bean>
在异常页面自动有exception对象。
SpringMVC学习资料