项目一直用着struts2,感觉用着也挺习惯,(除了低版本的struts有个漏洞,很容易给人攻击,不过高版本已经修复了),后来其他项目慢慢开始用spring mvc,也就看了一下spring mvc和struts2的区别。个人最大的感觉就是,跟spring的集成非常方便(因为都是spring的嘛,所以集成比struts方便多了)。同时感觉在设计上面,spring mvc 比struts2更加精细一些,基于reset风格的url,包括方法的调用和参数的传递都很不同。再有就是spring mvc支持的注解太强大了,完全可以基于注解进行驱动开发。
Spring mvc的基本逻辑不多讲,网上有非常多的文章,直接从配置讲起。
基于maven的pom.xml进行包的引入
<!-- spring begin -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring end -->
<!-- spring mvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- logging begin -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<!-- logging end -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<!-- common io 包支持 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
web.xml配置
整理配置很想STRUTS2的配置 ,主要是对url的进行拦截就是了。其中spring-mvc.xml 是关于spring MVC的具体配置
<!-- spring mvc 拦截 -->
<servlet>
<servlet-name>springMvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 默认获取web-inf下面的springServlet-mvc.xml ,可以自定义配置 -->
<param-value>classpath*:/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>20</session-timeout>
</session-config>
spring-mvc.xml
本文主要是基于reset风格的spring进行开发,用的注解驱动。
<?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-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 自动扫描且只扫描@Controller -->
<context:component-scan base-package="com.example.mvc" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
<!-- 添加注解驱动 -->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<!-- 将StringHttpMessageConverter的默认编码设为UTF-8 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8" />
</bean>
<!-- 将Jackson2HttpMessageConverter的默认格式化输出设为true -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="prettyPrint" value="true"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 定义JSP文件的位置 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 访问前缀 -->
<property name="prefix" value="/WEB-INF/views/"/>
<!-- 访问后缀 -->
<property name="suffix" value=".jsp"/>
</bean>
<!-- 对CSS ,图片等静态资源,不受spring-mvc可控制的资源,定义默认的handler,不然会报500错误 -->
<mvc:default-servlet-handler/>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean> </beans>
基于注解的control类HelloControl,该类其实就是起到一个控制器的作用,类似于struts2的 action。
类里面写了基本上各种情况的跳转,参数获取和提供给ajax调用的时候,如何来写。
package com.example.mvc;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.servlet.ModelAndView;
import com.example.hessian.Hello;
import com.example.mvc.pojo.User;
@Controller
@RequestMapping(value="hello")
public class HelloControl {
/**
* 最简单的spring mvc 跳转
* @return
*/
@RequestMapping(value="testMvcSimple")
public String testParam(){
return "hello";//跳转到hello这个视图
}
/* 以下为接受前端各种参数讲解 */
/**
* spring mvc 跳转,带返回值到页面
* @return
*/
@RequestMapping(value="testMvc")
public ModelAndView test(){
ModelAndView mv=new ModelAndView();
//传递数据
mv.addObject("userName", "jacky");
mv.addObject("age", "25");
//设置跳转过去的view
mv.setViewName("hello");
return mv;
}
/**
* spring mvc 跳转,带参数
* @return
*/
@RequestMapping(value="testMvcWithParam")
public ModelAndView test(String userName ,String age ){
ModelAndView mv=new ModelAndView();
//传递数据
mv.addObject(userName, age);
mv.addObject("age", "25");
//设置跳转过去的view
mv.setViewName("hello");
return mv;
}
/**
* spring mvc 跳转,pojo 参数
* @return
*/
@RequestMapping(value="testMvcWithPojoParam")
public ModelAndView test(User user ){
ModelAndView mv=new ModelAndView();
//传递数据
mv.addObject("user", user);
//设置跳转过去的view
mv.setViewName("hello");
return mv;
}
/**
* spring mvc 跳转, 文件参数,实现单个文件上传
* @return
*/
@RequestMapping(value="testMvcUploadFile")
public String test(@RequestParam("pic") CommonsMultipartFile file ,HttpServletRequest request,HttpServletResponse response){
File saveFile=new File("d://springmvc/upload/"+file.getFileItem().getName());
try {
FileUtils.writeByteArrayToFile(saveFile, file.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
return "hello";
}
/**
* spring mvc 跳转, 文件参数,实现多个文件上传
* @return
*/
@RequestMapping(value="testMvcUploadMultiFile")
public String test(@RequestParam MultipartFile[] pics ,HttpServletRequest request,HttpServletResponse response){
File saveFile=new File("d://springmvc/upload/"+pics[0].getOriginalFilename());
try {
FileUtils.writeByteArrayToFile(saveFile, pics[0].getBytes());
} catch (IOException e) {
e.printStackTrace();
}
return "hello";
}
/* ajax 上传单个或者多个文件,一般是前台使用ajaxFileUpload 插件配合,后台基本不需要改动 */
/*-------------华丽丽的分割线--------------------*/
/* 以下当前端为ajax调用,而不是跳转的情况,如何返回json类型的值 *
* 主要是 用到@ResponseBody 注解 ,把返回的结果按照spring-mvc.xml的配置,转换成json。
* 同 method = RequestMethod.GET ,用来限定是get 还是post等请求
* /
/**
* 最简单的,直接返回一个json格式的字符串
* @return
*/
@ResponseBody
@RequestMapping(value="testMvcReturnStr",method = RequestMethod.GET)
public Map<String,String> testReturnStr(){
Map<String,String> map=new HashMap<String,String>();
map.put("user", "jacky");
return map;
}
@ResponseBody
@RequestMapping(value="testMvcReturnObj",method = RequestMethod.GET)
public Hello testReturnObj(){
Hello hl=new Hello();
hl.setAge("21");
return hl;
}
@ResponseBody
@RequestMapping(value="testMvcReturnObjByObj",method = RequestMethod.GET)
public Hello testReturnObjByObj( Hello hl){
return hl;
}
@ResponseBody
@RequestMapping(value="testMvcReturnObjByObjs")
public List<Hello> testReturnObjByObjs(@RequestBody List<Hello> hls){
return hls;
}
}
package com.example.mvc.pojo;
public class User {
private String userName;
private String age;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
String basePath = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9" />
<title></title>
<script type="text/javascript" src="resources/js/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
function upload(){
document.uploadForm.submit();
}
function testMvcReturn(){
$.ajax({
url: "hello/testMvcReturnStr.do",
dataType: 'json',
success: function(result){
alert(result.user);
}
});
}
function testMvcReturnObjByObj(){
var hello={name:"jacky",age:"25"};
var array=[];
array.push(hello);
$.ajax({
url: "hello/testMvcReturnObjByObjs.do",
type:"post",
dataType: 'json',
contentType:"application/json",
data:JSON.stringify(array),
success: function(result){
alert(result.userName+","+result.age);
}
});
}
</script>
</head>
<body>
<a href="hello/testMvcSimple"> simple spring mvc </a>
<a href="hello/testMvc.do"> hello spring </a>
<a href="hello/testMvcWithParam?userName=jacky&age=25"> visi with param</a>
<p>上传单个文件</p>
<form action="hello/testMvcUploadMultiFile.do" method="post" enctype="multipart/form-data" name="uploadForm">
<input type="file" name="pics" />
<input type="button" value="上传" οnclick="upload();"/>
</form>
<p> <input type="button" οnclick="testMvcReturnObjByObj();" value="ajax simple " /> </p>
</body>
</html>
通过index.jsp 访问helloControl ,再回到hello.jsp
hello.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<p>hello spring mvc </p>
<p>普通参数展示</p>
<p>${userName },${age}</p>
<p>对象参数展示:</p>
<p>${user.userName },${user.age }</p>
</body>
</html>
测试访问
http://localhost:8080/SpringMvcSp/index.jsp
点击hello spring 跳转。