Day01-SpringMvc笔记
一、MVC思想&SpringMvc框架概念与特点
1.什么叫MVC思想
model --模型 view–视图 controller–控制器
模型:数据模型,负责封装应用程序数据在视图层展示,域对象(JavaBean Map List )
视图:只是展示这些数据jsp页面,不包含任何业务逻辑。
控制器:负责接收来自用户的请求,并调用后台服务(service 或者 dao)来处理业务逻辑。-Servlet 业务逻辑处理,页面转发。
MVC 模式的核心思想是将业务逻辑从界面中分离出来,允许它们单独改变而不会相互影响。
2.MVC框架
Jsp+servlet>struts1>spring mvc>struts2+freemarker>struts2,ognl,值栈。
开发效率上,基本正好相反。值得强调的是,spring mvc 开发效率和 struts2 不相上下,但从目前来看,spring mvc 的流行度已远远超过 struts2。
3.Spring MVC是什么
Spring MVC 是 Spring 家族中的一个 web 成员, 它是一种基于 Java 的实现了 Web MVC 设计思想的请求驱动类型的轻量级 Web 框架,即使用了 MVC 架构模式的思想,将 web 层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring MVC 也是要简化我们日常 Web 开发的。
Spring MVC 是服务到工作者思想的实现。前端控制器是 DispatcherServlet;应用控制器拆为处理器映射器(Handler Mapping)进行处理器管理和视图解析器(View Resolver) 进行视图管理;支持本地化/国际化(Locale)解析及文件上传等;提供了非常灵活的数据验证、格式化和数据绑定机制;提供了强大的约定大于配置(惯例优先原则)的契约式编程支持。
4.Spring MVC 特点
- 让我们能非常简单的设计出干净的 Web 层;
- 进行更简洁的 Web 层的开发;
- 天生与 Spring 框架集成(如 IoC 容器、AOP 等);
- 提供强大的约定大于配置的契约式编程支持;
- 能简单的进行 Web 层的单元测试;
- 支持灵活的 URL 到页面控制器的映射;
- 非常容易与其他视图技术集成,如 jsp、Velocity、FreeMarker 等等,因为模型数据不放在特定的 API 里,而是放在一个 Model 里(Map 数据结构实现,因此很容易被其他框架使用);
- 非常灵活的数据验证、格式化和数据绑定机制,能使用任何对象进行数据绑定,不必实现特定框架的 API;
- 支持灵活的本地化等解析;
- 更加简单的异常处理;
- 对静态资源的支持;
12.支持 Restful 风格。
二、SpringMvc请求流程&环境搭建与测试
1.Spring MVC 请求处理流程分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GlGMUt6p-1597568202656)(F:\A20200102\高级资源\Springmvc 框架\流程图.png)]
2.Spring MVC 环境搭建
2.1创建web工程
2.2添加依赖坐标
<!-- spring web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- spring mvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- web servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<build>
<finalName>springmvc01</finalName>
<plugins>
<!-- 编译环境插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version> <configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.25</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<contextPath>/springmvc01</contextPath>
</configuration>
</plugin>
</plugins>
</build>
2.3配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<!--
编码过滤器
前端控制器
-->
<filter>
<description>char encoding filter</description>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- servlet请求分发器 -->
<servlet>
<servlet-name>springMvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:servlet-context.xml</param-value>
</init-param>
<!-- 表示启动容器时初始化该Servlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<!-- 这是拦截请求, /代表拦截所有请求,拦截所有.do请求 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2.4配置servlet-context.xml
src/main/resources
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.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.xsd">
<!-- 扫描com.shsxt.controller 下包 -->
<context:component-scan base-package="com.shsxt.controller" />
<!-- mvc 请求映射 处理器与适配器配置-->
<mvc:annotation-driven/>
<!--配置视图解析器 默认的视图解析器- -->
<bean id="defaultViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="contentType" value="text/html" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
2.5添加控制器代码
com.shsxt.controller
package com.shsxt.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class HelloController {
// localhost:8080/springmvc/hello
@RequestMapping("hello")
public ModelAndView hello(){
ModelAndView mv =new ModelAndView();
/**
* 1.模型
* 2.视图
*/
mv.addObject("hello","hello SpringMvc");
mv.setViewName("hello");
return mv;
}
}
2.6添加视图
src/main/webapp/WEB-INF/jsp–>hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${hello}
</body>
</html>
2.7配置jetty启动命令
jetty:run -Djetty.port=8080
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QCSEu9oq-1597568202663)(F:\A20200102\高级资源\Springmvc 框架\2.png)]
2.8启动测试
localhost:8080/springmvc01/hello
三、参数绑定&URL地址映射配置&域对象配置
1.参数绑定
1.1基本类型|包装类型
基本类型
/**
* 基本类型参数绑定
* 参数值必须存在 如果未指定参数值 500错误
* 参数名与方法形参名必须一致
*/
@RequestMapping("p01")
public void p01(int id,int money){
System.out.println(id+"---"+money);
}
/**
* 基本类型参数绑定
* 参数值必须存在 如果未指定参数值 500错误
* 参数名与方法形参名必须一致
* 如果参数值未设置 可以通过@RequestParam
* defaultValue属性设置默认值
* name 设置形参别名
* @param id
* @param money
*/
@RequestMapping("p02")
public void p02(@RequestParam(name="userId",defaultValue="10") int id,@RequestParam(defaultValue="1000.0")double money){
System.out.println(id+"++++"+money);
}
包装类型
/**
* 包装类型参数值默认 null 推荐使用包装类型
* 如果参数值未设置 可以通过@RequestParam
* defaultValue 属性设置默认值
* name 设置参数别名
* 404错误:客户端错误 客户端传入的参数类型与后端方法形参的类型不匹配
* @param pageNum
* @param pageSize
*/
@RequestMapping("p03")
public void p03(@RequestParam(name="pn",defaultValue = "1") Integer pageNum,@RequestParam(name="ps") Integer pageSize){
System.out.println(pageNum+"---"+pageSize);
}
1.2 String|Date
/**
* 字符串类型:默认值为null
* @param userName
* @param userPwd
*/
@RequestMapping("p04")
public void p04(String userName,String userPwd){
System.out.println(userName+","+userPwd);
}
1.3 JavaBean 类型
/**
* JavaBean 类型
* url 参数名与JavaBean 成员属性名一致即可
* 注意日期绑定 需要在日期变量级别 声明@DateTimeFormat(pattern = "yyyy-MM-dd")
* @param accountQuery
*/
@RequestMapping("p05")
public void p05(AccountQuery accountQuery){
System.out.println(accountQuery);
}
AccountQuery 类
public class AccountQuery {
private Integer pageNum;
private Integer pageSize;
private String aname;
private String type;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date time;
private List<Integer> ids;
private Map<String,Object> map;
public List<Integer> getIds() {
return ids;
}
public Map<String, Object> getMap() {
return map;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
@Override
public String toString() {
return "AccountQuery{" +
"pageNum=" + pageNum +
", pageSize=" + pageSize +
", aname='" + aname + '\'' +
", type='" + type + '\'' +
", time=" + time +
'}';
}
public Integer getPageNum() {
return pageNum;
}
public void setPageNum(Integer pageNum) {
this.pageNum = pageNum;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public String getAname() {
return aname;
}
public void setAname(String aname) {
this.aname = aname;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
}
1.4数组
/**
* 数组参数:
* ids=xxx&ids=xxx&ids=xxx
* @param ids
*/
@RequestMapping("p06")
public void p06(Integer[] ids){
for(Integer id:ids){
System.out.println(id);
}
}
1.5 List集合
/**
* 集合类型参数 不能直接声明为方法形参
* 必须有JavaBean进行包装(作为JavaBean的成员变量实现参数绑定)
* List 集合 参数绑定 与数组绑定参数传入类似
* @param accountQuery
*/
@RequestMapping("p07")
public void p07(AccountQuery accountQuery){
accountQuery.getIds().forEach(id->{
System.out.println(id);
});
}
1.6 Map集合
/**
* Map集合
* map[key]=value&map[key]=value&map[key]=value
* @param accountQuery
*/
@RequestMapping("p08")
public void p08(AccountQuery accountQuery){
accountQuery.getMap().forEach((k,v)->{
System.out.println(k+"----"+v);
});
}
2.URL映射地址配置
url 到方法绑定
@RequestMapping
声明在类 + 方法级别
value:默认属性可以省略 配置 uri 地址 uri地址可以配置多个
如果类 方法级别均声明@RequestMapping uri 地址:类级别url/方法级别uri
method 配置方法支持的请求类型 默认Get + Post 均支持 显式声明method 方法支持具体请求类型
params :配置方法的形参 访问时以方法形参名称进行访问
@RequestMapping("u01")
public ModelAndView u01(){
ModelAndView mv=new ModelAndView();
mv.setViewName("hello");
mv.addObject("hello","u01");
return mv;
}
@RequestMapping(value = {"u02_01","u02_02"})
public ModelAndView u02(){
ModelAndView mv=new ModelAndView();
mv.setViewName("hello");
mv.addObject("hello","u02");
return mv;
}
@RequestMapping(value = {"u03_01","u03_02"},method = {RequestMethod.POST,RequestMethod.GET})
public ModelAndView u03(){
ModelAndView mv=new ModelAndView();
mv.setViewName("hello");
mv.addObject("hello","u03");
return mv;
}
@RequestMapping(params = "u04")
public ModelAndView u04(){
ModelAndView mv=new ModelAndView();
mv.setViewName("hello");
mv.addObject("hello","u04");
return mv;
}
3.域对象配置
/**
* 请求域对象设置
* 方法返回ModelAndView
* ModelAndView
* 方法返回字符串时
* ModelMap
* Model
* Map
* Request
* 内置对象声明
* 方法形参声明内置对象
* request response session
*/
@RequestMapping("s01")
public ModelAndView s01(){
ModelAndView mv=new ModelAndView();
mv.setViewName("hello");
mv.addObject("hello","s01");
return mv;
}
@RequestMapping("s02")
public String s02(ModelMap modelMap){
modelMap.addAttribute("hello","s02");
return "hello";
}
@RequestMapping("s03")
public String s03(Map map){
map.put("hello","s03");
return "hello";
}
@RequestMapping("s04")
public String s04(Model model){
model.addAttribute("hello","s04");
return "hello";
}
@RequestMapping("s05")
public String s05(HttpServletRequest request){
request.setAttribute("hello","s05");
return "hello";
}
@RequestMapping("s06")
public ModelAndView s06(HttpServletRequest request){
ModelAndView mv=new ModelAndView();
mv.setViewName("hello");
request.setAttribute("hello","s06");
return mv;
}
@RequestMapping("s07")
public ModelAndView s07(HttpSession session){
ModelAndView mv=new ModelAndView();
mv.setViewName("hello");
session.setAttribute("hello","s07");
return mv;
}
@RequestMapping("s08")
public ModelAndView s08(HttpSession session){
ModelAndView mv=new ModelAndView();
mv.setViewName("hello");
System.out.println(session.getAttribute("hello"));
return mv;
}
@RequestMapping("s09")
public void s09(HttpServletResponse response){
response.setContentType("application/json;charset=utf-8");
response.setCharacterEncoding("utf-8");
try {
PrintWriter pw=response.getWriter();
pw.write("{\"id\":20,\"userName\":\"admin\"}");
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
四、请求转发&重定向
1.重定向
@Controller
public class RedirectDispatcherController {
/**
* 请求转发 & 重定向
*/
@RequestMapping("r01")
public String r01(){
return "redirect:result.jsp";
}
@RequestMapping("r02")
public String r02(){
return "redirect:result.jsp?id=10&name=admin";
}
/**
* 重定向 如果存在中文参数值 默认乱码
*/
@RequestMapping("r03")
public String r03(){
return "redirect:result.jsp?id=10&name=张三";
}
/**
* RedirectAttributes 重定向参数 推荐使用 解决乱码
* @param redirectAttributes
* @return
*/
@RequestMapping("r04")
public String r04(RedirectAttributes redirectAttributes){
redirectAttributes.addAttribute("id",20);
redirectAttributes.addAttribute("name","李四");
return "redirect:result.jsp";
}
//重定向到方法
@RequestMapping("r05")
public String r05(RedirectAttributes redirectAttributes){
redirectAttributes.addAttribute("id",20);
redirectAttributes.addAttribute("name","李四");
return "redirect:test";
}
@RequestMapping("r06")
public ModelAndView r06(){
ModelAndView mv=new ModelAndView();
mv.setViewName("redirect:test");
mv.addObject("id",20);
mv.addObject("name","李四");
return mv;
}
}
test类
@Controller
public class TestController {
@RequestMapping("test")
public void test(Integer id,String name){
System.out.println(id+","+name);
}
@RequestMapping("test02")
public void test02(){
System.out.println("test02..........");
}
}
2.请求转发
//默认是请求转发
// 转发到 一个新的方法时
@RequestMapping("r07")
public ModelAndView r07(){
ModelAndView mv=new ModelAndView();
mv.addObject("hello","r07");
mv.setViewName("forward:test02");
return mv;
}
Day02-SpringMvc笔记
一、SpringMvc转换JSON数据
1.基本概念
@ResponseBody 响应体注解
声明级别: 类级别 方法级别(使用较多)
默认作为 请求的响应体内容 json 数据
@RequestBody
声明级别:方法形参类型前面
默认为请求体内容 格式为json 数据
2.添加配置
添加json依赖坐标
<!-- 添加json 依赖jar包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.7.0</version>
</dependency>
添加json转换器配置
servlet-context.xml
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
3.注解使用
User类
public class User {
private Integer id;
private String userName;
public User() {
}
public User(Integer id, String userName) {
this.id = id;
this.userName = userName;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
@RequestMapping("user")
public class UserController {
private Map<Integer, User> users;
public UserController(){
users=new HashMap<>();
users.put(10,new User(10,"admin"));
users.put(20,new User(20,"test"));
}
@RequestMapping("login")
public void login(HttpSession session){
System.out.println("用户登录....");
session.setAttribute("userInfo",new User(10,"admin"));
}
@RequestMapping("queryUserByUserId")
@ResponseBody
public User queryUserById(Integer userId){
return users.get(userId);
}
@RequestMapping("queryUserByUserId02")
public @ResponseBody User queryUserById02(Integer userId){
return users.get(userId);
}
@RequestMapping("list")
@ResponseBody
public List<User> queryUsers(){
return Arrays.asList(new User(10,"admin"),new User(20,"test"));
}
@RequestMapping("list02")
@ResponseBody
public Map<Integer,User> queryUsers02(){
return users;
}
@RequestMapping("list03")
@ResponseBody
public List<Map<String,User>> queryUsers03(){
Map<String,User> map01=new HashMap<>();
map01.put("admin",new User(10,"admin"));
Map<String,User> map02=new HashMap<>();
map02.put("test",new User(20,"test"));
return Arrays.asList(map01,map02);
}
//请求
@RequestMapping("queryUser")
@ResponseBody
public User queryUser(@RequestBody User user){
return user;
}
@RequestMapping("test")
@ResponseBody
public ParamModel test(@RequestBody ParamModel paramModel){
return paramModel;
}
}
二、拦截器
1.定义拦截器二种方法
实现接口:HandlerInterceptor
继承: HandlerInterceptorAdapter
2.配置拦截器
servlet-context.xml
方式一:
<!--
拦截器生效配置-01
MyInterceptor01 拦截器 拦截所有的资源
-->
<mvc:interceptors>
<bean class="com.shsxt.interceptors.MyInterceptor01"></bean>
</mvc:interceptors>
public class MyInterceptor01 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("MyInterceptor01-->preHandle-->在Handler 方法执行前执行preHandler方法");
return true;
/**
* 方法
* 返回true: 执行目标方法
* 返回false: 禁止目标方法执行
*/
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor01-->postHandle-->在Hander方法执行后未生成视图前执行postHandle方法");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("MyInterceptor01-->afterCompletion-->在Handler 方法执行后并且完成视图生成执行afterCompletion");
}
}
方式二:
<!--
拦截器生效配置-02
mvc:mapping path :配置拦截的资源 可以配置多个
/**:拦截所有资源
mvc:exclude-mapping path :配置放行资源 可以配置多个
-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/url/**"/>
<mvc:mapping path="/p01"/>
<mvc:exclude-mapping path="/user/login"/>
<bean class="com.shsxt.interceptors.MyInterceptor01"></bean>
</mvc:interceptor>
</mvc:interceptors>
方式三:多个拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/url/**"/>
<mvc:mapping path="/p01"/>
<mvc:exclude-mapping path="/user/login"/>
<bean class="com.shsxt.interceptors.MyInterceptor01"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.shsxt.interceptors.MyInterceptor03"></bean>
</mvc:interceptor>
</mvc:interceptors>
public class MyInterceptor03 extends HandlerInterceptorAdapter{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor03-->preHandle-->在Handler 方法执行前执行preHandler方法");
return true;
}
}
3.用户登录拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/user/login"/>
<bean class="com.shsxt.interceptors.NoLoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
public class NoLoginInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
/**
* 判断session中用户信息是否存在
* 存在 放行
* 不存在 重定向到login
*/
User user= (User) request.getSession().getAttribute("userInfo");
if(null==user){
response.sendRedirect(request.getContextPath()+"/login.jsp");
return false;
}
return true;
}
}
三、SpringMvc文件上传
1.添加配置
添加文件上传依赖坐标
<!--文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
<!--jstl-->
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
配置文件上传解析器
servlet-context.xml
<!--
配置文件上传解析器
-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize">
<value>104857600</value>
</property>
<property name="maxInMemorySize">
<value>4096</value>
</property>
</bean>
2.文件上传使用
@Controller
public class FileController {
@RequestMapping("/upload")
public String uploadFile(HttpServletRequest request){
MultipartHttpServletRequest mhsr= (MultipartHttpServletRequest) request;
//获取上传的临时文件
MultipartFile mf=mhsr.getFile("file");
if(null!=mf && mf.getSize()>0){
String basePath=request.getSession().getServletContext().getRealPath("/");
File file=new File(basePath+"/upload");
if(!(file.exists())){
file.mkdir();
}
/**
* 文件名定义
* 1.获取原始文件名(可能出现文件名冲突)
* 2.创建新的文件名(文件名唯一)
* 2.1 年月日时分秒.png|jpg|gif
* 2.2 获取系统当前时间毫秒数
* 2.3 UUID 随机 不重复 32字符串
*/
String fileName= UUID.randomUUID().toString().replace("-","");
mf.getOriginalFilename().substring(mf.getOriginalFilename().lastIndexOf("."));
try {
mf.transferTo(new File(file,fileName));
request.setAttribute("result","文件上传成功!");
} catch (IOException e) {
e.printStackTrace();
request.setAttribute("result","文件上传失败!");
}
}else{
request.setAttribute("result","文件上传失败!");
}
return "result";
}
}
result.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${result}
</body>
</html>
四、SSM框架集成
1.集成配置
添加依赖坐标
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.shsxt</groupId>
<artifactId>ssm</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>ssm Maven Webapp</name>
<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>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- spring 测试 jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- spring jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- spring 事物 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- aspectj 切面编程的 jar -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<!-- c3p0 连接池 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<!-- 添加 mybatis 与 Spring 整合的核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!-- mysql 驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
<!-- 日志打印相关的 jar -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.11</version>
</dependency>
<!-- spring web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- spring mvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- web servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<!-- 添加json 依赖jar包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.7.0</version>
</dependency>
<!--文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
</dependencies>
<build>
<finalName>ssm</finalName>
<!--
Maven 项目
如果源代码(src/main/java)存在xml properties tld 等文件 maven 默认不会自动编译该文件到输出目录
如果要编译源代码中xml properties tld 等文件 需要显式配置resources 标签
-->
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
<!--jetty-->
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.25</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<contextPath>/ssm</contextPath>
</configuration>
</plugin>
</plugins>
</build>
</project>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<description>char encoding filter</description>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>springMvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<!-- <url-pattern>*.do</url-pattern>-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
添加servlet-context.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.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.xsd">
<!-- 扫描com.shsxt.controller 下包 -->
<context:component-scan base-package="com.shsxt.controller" />
<!-- mvc 请求映射 处理器与适配器配置-->
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
<!--配置视图解析器 默认的视图解析器- -->
<bean id="defaultViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="contentType" value="text/html" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!--
配置文件上传解析器
-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize">
<value>104857600</value>
</property>
<property name="maxInMemorySize">
<value>4096</value>
</property>
</bean>
<!--
放行静态资源 SpringMvc框架不做处理 直接响应给浏览器
-->
<mvc:default-servlet-handler/>
<!--
全局异常统一处理-01
处理应用程序视图异常 无法处理方法响应json 的情况
-->
<!--<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="error"></property>
<property name="exceptionAttribute" value="ex"></property>
<property name="exceptionMappings">
<props>
<prop key="com.shsxt.exceptions.ParamsException">param-error</prop>
<prop key="com.shsxt.exceptions.NoLoginException">no-login-error</prop>
</props>
</property>
</bean>-->
</beans>
spring.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- 配置扫描器 -->
<context:component-scan base-package="com.shsxt">
<!--除了controller层不扫描-->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--properties 文件加载配置-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--
c3p0数据源配置
-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.uname}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--自动化注入-->
<aop:aspectj-autoproxy/>
<!--
事物管理器
-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"></tx:method>
<tx:method name="del*" propagation="REQUIRED"></tx:method>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="cut" expression="execution(* com.shsxt.service..*.*(..))"/>
<aop:advisor pointcut-ref="cut" advice-ref="txAdvice"></aop:advisor>
</aop:config>
<!--
Mybatis 整合Spring
-->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!--
mybatis 全局配置文件
-->
<property name="configLocation" value="classpath:mybatis.xml"></property>
<!--
sql 映射文件
-->
<property name="mapperLocations" value="classpath:com/shsxt/mappers/*.xml"></property>
</bean>
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.shsxt.dao"></property>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"></property>
</bean>
</beans>
2.测试使用
@Controller
public class IndexController{
@Resource
private IndexService indexService;
@RequestMapping("index")
public String index(HttpServletRequest request){
request.setAttribute("msg","hello ssm");
return "index";
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
3.静态文件处理
@Controller
public class IndexController{
@Resource
private IndexService indexService;
@RequestMapping("index")
public String index(HttpServletRequest request){
request.setAttribute("msg","hello ssm");
//放入上下文路径/ssm
request.setAttribute("ctx",request.getContextPath());
return "index";
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<%--引入css--%>
<link rel="stylesheet" href="${ctx}/statics/css/user.css">
</head>
<body>
${msg}
<img src="${ctx}/statics/images/2.jpg">
</body>
</html>
拦截器
web.xml
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<!-- <url-pattern>*.do</url-pattern>-->
<url-pattern>/</url-pattern>
</servlet-mapping>
五、SpringMvc全局异常统一处理
1.全局异常处理方式一
<!--
全局异常统一处理-01
处理应用程序视图异常 无法处理方法响应json 的情况
-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!--视图-->
<property name="defaultErrorView" value="error"></property>
<!--异常信息-->
<property name="exceptionAttribute" value="ex"></property>
<!--分类异常-->
<property name="exceptionMappings">
<props>
<prop key="com.shsxt.exceptions.ParamsException">param-error</prop>
<prop key="com.shsxt.exceptions.NoLoginException">no-login-error</prop>
</props>
</property>
</bean>
<%-- error.jsp--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
服务器错误,请稍后再试.....${ex}
</body>
</html>
<%-- param-error.jsp--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
参数异常页面---${ex}
</body>
</html>
<%-- no-login-error.jsp--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
未登录异常页面-----${ex}
</body>
</html>
/**
* 自定义参数异常 ParamsException
*/
public class ParamsException extends RuntimeException{
private Integer code=300;
private String msg="参数异常!";
public ParamsException(){
super("参数异常!");
}
public ParamsException(String msg){
super(msg);
this.msg=msg;
}
public ParamsException(Integer code) {
super("参数异常!");
this.code = code;
}
public ParamsException(String msg, Integer code) {
super(msg);
this.code = code;
this.msg=msg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
/**
* 自定义参数异常 NoLoginException
*/
public class NoLoginException extends RuntimeException{
private Integer code=500;
private String msg="未登录异常!";
public NoLoginException() {
super("未登录异常!");
}
public NoLoginException(Integer code) {
super("未登录异常!");
this.code = code;
}
public NoLoginException(String msg) {
super(msg);
this.msg = msg;
}
public NoLoginException(Integer code, String msg) {
super(msg);
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
/**
* service 层 处理异常
*/
@Service
public class IndexService {
public void test(){
if(1==1){
throw new ParamsException("异常测试!");
}
}
public void test2(){
if(1==1){
throw new NoLoginException();
}
}
}
2.全局异常处理方式二
@Component
public class GlobalException implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception ex) {
/**
* 第二种全局异常配置
* */
/* ModelAndView mv=new ModelAndView();
mv.setViewName("error");
mv.addObject("ex",ex);
//判断参数异常
if(ex instanceof ParamsException){
ParamsException pe= (ParamsException) ex;
mv.setViewName("param-error");
mv.addObject("ex",pe.getMsg());
}
//判断是否登录异常
if(ex instanceof NoLoginException){
NoLoginException ne= (NoLoginException) ex;
mv.setViewName("no-login-error");
mv.addObject("ex",ne.getMsg());
}
return mv;*/
//数据转换成json数据
String result="{\"code\":300,\"msg\":\"默认错误\"}";
PrintWriter pw=null;
try {
httpServletResponse.setContentType("application/json;charset=utf-8");
httpServletResponse.setCharacterEncoding("utf-8");
pw=httpServletResponse.getWriter();
pw.write(result);
pw.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(null !=pw){
pw.close();
}
}
return null;
}
}
3.全局异常处理方式三
/**
* 注解异常配置 继承思想
*/
@Controller
public class BaeController {
@ExceptionHandler(value = Exception.class)
public ModelAndView resolveException(Exception ex) {
ModelAndView mv=new ModelAndView();
mv.setViewName("error");
mv.addObject("ex",ex);
//判断参数异常
if(ex instanceof ParamsException){
ParamsException pe= (ParamsException) ex;
mv.setViewName("param-error");
mv.addObject("ex",pe.getMsg());
}
//判断是否登录异常
if(ex instanceof NoLoginException){
NoLoginException ne= (NoLoginException) ex;
mv.setViewName("no-login-error");
mv.addObject("ex",ne.getMsg());
}
return mv;
}
}
@Controller
public class IndexController extends BaeController{
@Resource
private IndexService indexService;
@RequestMapping("index")
public String index(HttpServletRequest request){
request.setAttribute("msg","hello ssm");
//放入上下文路径/ssm
request.setAttribute("ctx",request.getContextPath());
// int i=1/0;
indexService.test();
indexService.test2();
return "index";
}
}