WEBAPP基础
通过url找到对应的servlet
<!--注册servlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.han.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
servlet用来处理请求方法(常用的method:get、post)
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
/* http://localhost:8080/hello?method=delete */
//1、获取参数
String method = req.getParameter("method");
if("add".equals(method)){
req.getSession().setAttribute("msg","执行了add方法");
} else if("delete".equals(method)){
req.getSession().setAttribute("msg","执行了delete方法");
}
//2、调用业务层
//3、视图转发或重定向
req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,resp);// '/'开头的是绝对路径从根目录开始
// resp.sendRedirect();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
SpringMVC
基础SpringMVC Demo
核心servlet:所有请求的servlet都统一让DispatcherServlet来分发调度,统一管理servlet
web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--注册DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--DispatcherServlet要绑定的配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!--启动级别 1-->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- / 匹配所有的请求(不包括.jsp)-->
<!-- /* 匹配所有的请求(包括.jsp)-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
SpringMVC原理图
Spring的web框架围绕DispatcherServlet设计。DispatcherServlet的作用是将请求分发到不同的处理器。
配置文件:springmvc-servlet.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--写死-->
<!-- 处理器映射器 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!-- 处理器适配器 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--处理器视图解析器DispatcherServlet提供的ModelAndView
1、获取了ModelAndView的数据
2、解析ModelAndView的视图名字
3、拼接视图名字,找到对应的视图 /WEB-INF/jsp/hello.jsp
4、将数据渲染到这个视图上
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!--注入controller;id为请求地址-->
<bean id="/hello" class="com.han.controller.HelloController"/>
</beans>
HelloController
package com.han.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloController implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//ModeAndView 模型和视图
ModelAndView mv = new ModelAndView();
//封装对象,放在ModelAndView中 这个应该是类似于JSON对象
mv.addObject("msg","HelloSpringMVC!");
//封装要跳转的视图,放在ModelAndView中
mv.setViewName("hello"); //通过视图解析器解析成: /WEB-INF/jsp/hello.jsp
return mv;
}
}
@RequestMapping
注解变体
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
指定method
@RequestMapping(path = "url地址",method = RequestMethod.GET)
Annotation(注解)开发
@Component
自动将类对象注入到IOC容器中,其中@Controller(控制层)、@Service(业务层)、@Repository(dao层) 均继承至它
配置文件:springmvc-servlet.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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 自动扫描包,让指定包下的注解生效,全部注入IOC容器由IOC容器统一管理 -->
<context:component-scan base-package="com.han.controller"/>
<!-- 让Spring MVC不处理静态资源 -->
<mvc:default-servlet-handler />
<!--
支持mvc注解驱动
在spring中一般采用@RequestMapping注解来完成映射关系
要想使@RequestMapping注解生效
必须向上下文中注册DefaultAnnotationHandlerMapping(处理器映射器)
和一个AnnotationMethodHandlerAdapter(处理器适配器)实例
这两个实例分别在类级别和方法级别处理。
而annotation-driven配置帮助我们自动完成上述两个实例的注入。
-->
<mvc:annotation-driven />
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 后缀 -->
<property name="suffix" value=".jsp" />
</bean>
</beans>
HelloController
@RequestMapping 以客户端请求method为get来处理
@Controller
@RequestMapping("/HelloController")
public class HelloController {
//真实访问地址 : 域名/HelloController/hello
@RequestMapping("/hello")
public String sayHello(Model model){
//向模型中添加属性msg与值,可以在JSP页面中取出并渲染
model.addAttribute("msg","hello,SpringMVC");
//web-inf/jsp/hello.jsp
return "hello";
}
}
Controller层的各种形式
视图复用
@Controller
public class HelloController {
@RequestMapping("/t1")
public String test1 (Model model){
model.addAttribute("msg","Hello!test1");
return "test";
}
@RequestMapping("/t2")
public String test2 (Model model){
model.addAttribute("msg","Hello!test2");
return "test";
}
}
不依赖视图解析器(转发与重定向)
@Controller
public class ModelTest {
//无需视图解析器的转发与重定向
@RequestMapping("m1")
public String test1(Model model){
model.addAttribute("msg","ModelTest1");
return "/WEB-INF/jsp/test.jsp";//转发1
}
@RequestMapping("m2")
public String test2(Model model){
model.addAttribute("msg","中文:ModelTest2");
return "forward:/WEB-INF/jsp/test.jsp";//转发2
}
@RequestMapping("m3")
public String test3(Model model){
model.addAttribute("msg","ModelTest3");
return "redirect:/index.jsp";//重定向
}
//需视图解析器的转发与重定向
@RequestMapping("m4")
public String test4(Model model){
model.addAttribute("msg","ModelTest4");
return "test";//转发
}
@RequestMapping("m5")
public String test5(Model model){
model.addAttribute("msg","中文:ModelTest5");
return "redirect:m4";//重定向到m4
}
}
RESTful风格Controller
@Controller
public class RESTfulController {
//原来的:http://localhost:8080/add?a=1&b=2
@RequestMapping("/add")
public String test1(int a,int b,Model model){
int res = a + b;
model.addAttribute("msg",res);
return "test";
}
//RESTful: http://localhost:8080/add/1/2
//@RequestMapping(path = "/add/{a}/{b}",method = RequestMethod.GET)
@GetMapping("/add/{a}/{b}")
public String test2(@PathVariable int a,@PathVariable int b, Model model){
int res = a+b;
model.addAttribute("msg",res);
return "test";
}
}
返回JSON对象
json本质是字符串
统一解决乱码
<mvc:annotation-driven>
<!--统一解决了乱码-->
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
Controller
@ResponseBody 会跳过视图解析器,直接返回一个字符串
/*
返回json字符串统一解决:
在类上直接使用 @RestController ,这样子,里面所有的方法都只会返回 json 字符串了,不用再每一个都添加@ResponseBody !
我们在前后端分离开发中,一般都使用 @RestController ,十分便捷!
*/
@Controller
@RestController
public class UserController {
//解决乱码老办法:produces = "application/json;charset=utf-8"
//新办法可以直接配置SpringMVC来处理
@RequestMapping(value = "/j1",produces = "application/json;charset=utf-8")
@ResponseBody //会跳过视图解析器,直接返回一个字符串
public String test1(){
return new User("韩艺松j1","男",3).toString();
}
//对象转json
@RequestMapping(value = "/j2")
@ResponseBody //已经有@RestController,@ResponseBody可有可无
public String test2() throws JsonProcessingException {
User user = new User("韩艺松j2","男",3);
//创建一个jackson的对象映射器,用来解析数据
ObjectMapper mapper = new ObjectMapper();
//将我们的对象解析成为json格式
String str = mapper.writeValueAsString(user);
//由于@ResponseBody注解,这里会将str转成json格式返回;十分方便
return str;
}
//list转json map转json 结论:json本质就是个字符串
@RequestMapping(value = "/j3")
public String test3() throws JsonProcessingException {
List list = new ArrayList<User>();
Map map = new HashMap<User,Integer>();
for(int i = 0; i < 10; i++){
map.put(new User("韩艺松"+i,"男",3),i);
list.add(new User("韩艺松"+i,"男",3));
}
//创建一个jackson的对象映射器,用来解析数据
ObjectMapper mapper = new ObjectMapper();
//将我们的对象解析成为json格式
String str = mapper.writeValueAsString(list);
String mapStr = mapper.writeValueAsString(map);
//由于@ResponseBody注解,这里会将str转成json格式返回;十分方便
return str;
}
//时间转json jackson默认时间会转为时间差格式,所以要改成"yyyy-MM-dd HH:mm:ss"格式
@RequestMapping(value = "/j4")
@ResponseBody //已经有@RestController,@ResponseBody可有可无
public String test4() throws JsonProcessingException {
Date date = new Date();
String str = Time2JsonUtil.getJson(date);
return str;
}
}
时间格式转化工具类
类名的2等同于to,这里为了偷懒写成2
public class Time2JsonUtil {
public static String getJson(Object o){
return getJson(o,"yyyy-MM-dd HH:mm:ss");
}
public static String getJson(Object o,String dateFormat){
ObjectMapper mapper = new ObjectMapper();
//不使用时间差的方式
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
//自定义日期格式对象
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
mapper.setDateFormat(sdf);
String str = null;
try {
str = mapper.writeValueAsString(o);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return str;
}
}
整合Spring、SpringMVC、Mybatis(SSM,一定要烂熟于❤)
database.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
jdbc.username=root
jdbc.password=1234
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 这里的配置均可通过mybatis-spring配置,所以可写可不写 -->
<typeAliases>
<!-- 设置别名后com.han.pojo.User在Mapper中写User就可 -->
<package name="com.han.pojo"/>
</typeAliases>
<mappers>
<!-- 获得Mapper配置文件 -->
<mapper resource="com/han/dao/BookMapper.xml"/>
</mappers>
</configuration>
整合spring配置文件applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="spring/spring-dao.xml"/>
<import resource="spring/spring-service.xml"/>
<import resource="spring/spring-mvc.xml"/>
</beans>
spring-dao.xml
mapper实例获得过程
- 读取database.properties信息
- 通过c3p0获得数据库连接池dataSource
- 配置SqlSessionFactoryBean(dataSource : dataSource、configLocation : mybatis-config.xml)获得SqlSessionFactory
- 配置扫描Dao接口( MapperScannerConfigurer ),注入sqlSessionFactory和basePackage(需要扫描的Dao接口位置),动态实现Dao接口注入到spring容器中
- 获得mapper
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置整合mybatis -->
<!-- 1.关联数据库文件 -->
<context:property-placeholder location="classpath:database.properties"/>
<!-- 2.数据库连接池 -->
<!--数据库连接池
dbcp 半自动化操作 不能自动连接
c3p0 自动化操作(自动的加载配置文件 并且设置到对象里面)
-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 配置连接池属性 -->
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- c3p0连接池的私有属性 -->
<property name="maxPoolSize" value="30"/>
<property name="minPoolSize" value="10"/>
<!-- 关闭连接后不自动commit -->
<property name="autoCommitOnClose" value="false"/>
<!-- 获取连接超时时间 -->
<property name="checkoutTimeout" value="10000"/>
<!-- 当获取连接失败重试次数 -->
<property name="acquireRetryAttempts" value="2"/>
</bean>
<!-- 3.配置SqlSessionFactory对象 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource"/>
<!-- 配置MyBatis全局配置文件:mybatis-config.xml -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!-- 4.配置扫描Dao接口包,动态实现Dao接口注入到spring容器中 -->
<!--解释 :https://www.cnblogs.com/jpfss/p/7799806.html-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入sqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!-- 给出需要扫描Dao接口包 -->
<property name="basePackage" value="com.han.dao"/>
</bean>
</beans>
spring-mvc.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/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
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 配置SpringMVC -->
<!-- 1.开启SpringMVC注解驱动 -->
<mvc:annotation-driven />
<!-- 2.静态资源默认servlet配置-->
<mvc:default-servlet-handler/>
<!-- 3.配置jsp 显示ViewResolver视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- 4.扫描web相关的bean,注入到IOC容器中 -->
<context:component-scan base-package="com.han.controller" />
</beans>
spring-service.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"
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">
<!-- 扫描service相关的bean -->
<context:component-scan base-package="com.han.service" />
<!--BookServiceImpl注入到IOC容器中-->
<bean id="BookServiceImpl" class="com.han.service.BookServiceImpl">
<!--ref="bookMapper" 这个bookMapper是通过MapperScannerConfigurer自动获得的-->
<property name="bookMapper" ref="bookMapper"/>
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
Java代码
controller
BookController
@Controller
@RequestMapping("/book")
public class BookController {
@Autowired //自动注入
@Qualifier("BookServiceImpl") //指定bean id
private BookService bookService;
@RequestMapping("/allBook")
public String list(Model model) {
List<Books> list = bookService.queryAllBook();
model.addAttribute("list", list);
return "allBook";
}
@RequestMapping("/toAddBook")
public String toAddPaper() {
return "addBook";
}
@RequestMapping("/addBook")
public String addPaper(Books books) {
System.out.println(books);
bookService.addBook(books);
return "redirect:/book/allBook";
}
@RequestMapping("/toUpdateBook")
public String toUpdateBook(Model model, int id) {
Books books = bookService.queryBookById(id);
System.out.println(books);
model.addAttribute("book",books );
return "updateBook";
}
@RequestMapping("/updateBook")
public String updateBook(Model model, Books book) {
System.out.println(book);
bookService.updateBook(book);
Books books = bookService.queryBookById(book.getBookID());
model.addAttribute("books", books);
return "redirect:/book/allBook";
}
@RequestMapping("/del/{bookId}")
public String deleteBook(@PathVariable("bookId") int id) {
bookService.deleteBookById(id);
return "redirect:/book/allBook";
}
}
dao
BookMapper
public interface BookMapper {
//增加一个Book
int addBook(Books book);
//根据id删除一个Book
int deleteBookById(int id);
//更新Book
int updateBook(Books books);
//根据id查询,返回一个Book
Books queryBookById(int id);
//查询全部Book,返回list集合
List<Books> queryAllBook();
}
BookMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.han.dao.BookMapper">
<!--增加一个Book-->
<insert id="addBook" parameterType="Books">
insert into ssmbuild.books(bookName,bookCounts,detail)
values (#{bookName}, #{bookCounts}, #{detail})
</insert>
<!--根据id删除一个Book-->
<delete id="deleteBookById" parameterType="int">
delete from ssmbuild.books where bookID=#{bookID}
</delete>
<!--更新Book-->
<update id="updateBook" parameterType="Books">
update ssmbuild.books
set bookName = #{bookName},bookCounts = #{bookCounts},detail = #{detail}
where bookID = #{bookID}
</update>
<!--根据id查询,返回一个Book-->
<select id="queryBookById" resultType="Books">
select * from ssmbuild.books
where bookID = #{bookID}
</select>
<!--查询全部Book-->
<select id="queryAllBook" resultType="Books">
SELECT * from ssmbuild.books
</select>
</mapper>
service
BookService
public interface BookService {
//增加一个Book
int addBook(Books book);
//根据id删除一个Book
int deleteBookById(int id);
//更新Book
int updateBook(Books books);
//根据id查询,返回一个Book
Books queryBookById(int id);
//查询全部Book,返回list集合
List<Books> queryAllBook();
}
BookServiceImpl
public class BookServiceImpl implements BookService {
//调用dao层的操作,设置一个set接口,方便Spring管理
private BookMapper bookMapper;
public void setBookMapper(BookMapper bookMapper) {
this.bookMapper = bookMapper;
}
public int addBook(Books book) {
return bookMapper.addBook(book);
}
public int deleteBookById(int id) {
return bookMapper.deleteBookById(id);
}
public int updateBook(Books books) {
return bookMapper.updateBook(books);
}
public Books queryBookById(int id) {
return bookMapper.queryBookById(id);
}
public List<Books> queryAllBook() {
return bookMapper.queryAllBook();
}
}
pojo
Book
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Books {
private int bookID;
private String bookName;
private int bookCounts;
private String detail;
}
WEB配置
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--DispatcherServlet-->
<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:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--encodingFilter-->
<filter>
<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>
<!--Session过期时间-->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE HTML>
<html>
<head>
<title>首页</title>
<style type="text/css">
a {
text-decoration: none;
color: black;
font-size: 18px;
}
h3 {
width: 180px;
height: 38px;
margin: 100px auto;
text-align: center;
line-height: 38px;
background: deepskyblue;
border-radius: 4px;
}
</style>
</head>
<body>
<h3>
<a href="${pageContext.request.contextPath}/book/allBook">点击进入列表页</a>
</h3>
</body>
</html>
addBook.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>新增书籍</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 引入 Bootstrap -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>新增书籍</small>
</h1>
</div>
</div>
</div>
<form action="${pageContext.request.contextPath}/book/addBook" method="post">
书籍名称:<input type="text" name="bookName"><br><br><br>
书籍数量:<input type="text" name="bookCounts"><br><br><br>
书籍详情:<input type="text" name="detail"><br><br><br>
<input type="submit" value="添加">
</form>
</div>
allBook.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>书籍列表</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 引入 Bootstrap -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>书籍列表 —— 显示所有书籍</small>
</h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 column">
<a class="btn btn-primary" href="${pageContext.request.contextPath}/book/toAddBook">新增</a>
</div>
</div>
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>书籍编号</th>
<th>书籍名字</th>
<th>书籍数量</th>
<th>书籍详情</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach var="book" items="${requestScope.get('list')}">
<tr>
<td>${book.getBookID()}</td>
<td>${book.getBookName()}</td>
<td>${book.getBookCounts()}</td>
<td>${book.getDetail()}</td>
<td>
<a href="${pageContext.request.contextPath}/book/toUpdateBook?id=${book.getBookID()}">更改</a> |
<a href="${pageContext.request.contextPath}/book/del/${book.getBookID()}">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
updateBook.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>修改信息</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 引入 Bootstrap -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>修改信息</small>
</h1>
</div>
</div>
</div>
<form action="${pageContext.request.contextPath}/book/updateBook" method="post">
<input type="hidden" name="bookID" value="${book.getBookID()}"/>
书籍名称:<input type="text" name="bookName" value="${book.getBookName()}"/>
书籍数量:<input type="text" name="bookCounts" value="${book.getBookCounts()}"/>
书籍详情:<input type="text" name="detail" value="${book.getDetail() }"/>
<input type="submit" value="提交"/>
</form>
</div>
interceptor拦截器
拦截Demo
spring-servlet.xml配置
<!--关于拦截器的配置-->
<mvc:interceptors>
<mvc:interceptor>
<!--/** 包括路径及其子路径-->
<!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截-->
<!--/admin/** 拦截的是/admin/下的所有-->
<mvc:mapping path="/**"/>
<!--bean配置的就是拦截器-->
<bean class="com.han.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
拦截层MyInterceptor
public class MyInterceptor implements HandlerInterceptor {
//请求处理的方法之前执行
//如果返回true执行下一个拦截器
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("----------------处理前----------------");
return true;
}
//在请求处理方法执行之后执行
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("----------------处理后----------------");
}
//在dispatcherServlet处理后执行,做清理工作.
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("----------------清理----------------");
}
}
控制层
@Controller
public class InterceptorController {
@RequestMapping("/interceptor")
@ResponseBody
public String testFunction(){
System.out.println("控制器中的方法执行");
return "hello";
}
}
运行控制台输出
----------------处理前----------------
控制器中的方法执行
----------------处理后----------------
----------------清理----------------
登录与登出
spring-servlet.xml配置
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.han.interceptor.LoginInterceptor" id="interceptor"/>
</mvc:interceptor>
</mvc:interceptors>
登录请求拦截LoginInterceptor
public class LoginInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//如果是登录页面则放行
//contains方法:匹配String中是否有子串
if(request.getRequestURI().contains("Login")){
return true;
}
//如果用户已登录也放行
HttpSession session = request.getSession();
if(session.getAttribute("user") != null){
return true;
}
//如果用户没登录跳转到登录页面
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
return false;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
控制层UserController
@Controller
@RequestMapping("/user")
public class UserController {
//跳转到登录页面
@RequestMapping("/jumplogin")
public String jumpLogin(){
return "login";
}
//跳转到成功页面
@RequestMapping("/jumpsuccess")
public String jumpSuccess(){
return "success";
}
//登录提交
@RequestMapping("/Login")
public String login(HttpSession session,String username,String pwd){
// System.out.println("接收前端==="+username);
//session记录用户身份信息
session.setAttribute("user",username);
return "success";
}
//退出登录
@RequestMapping("logout")
public String LoginOut(HttpSession session){
//session 过期
session.invalidate();
return "login";
}
}
文件上传于下载
@Controller
public class FileController {
@RequestMapping("/test")
@ResponseBody
public String test(){
return "Hello";
}
//@RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象
//批量上传CommonsMultipartFile则为数组即可
@RequestMapping("/upload")
public String fileUpload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
//获取文件名:file.getOriginalFilename();
String uploadFileName = file.getOriginalFilename();
//如果文件名为空,直接回到首页!
if("".equals(uploadFileName)){
return "redirect:/index.jsp";
}
System.out.println("上传文件名:"+uploadFileName);
//上传路径保存设置
String path = request.getServletContext().getRealPath("/upload");
//如果路径不存在,创建一个
File realPath = new File(path);
if(!realPath.exists()){
realPath.mkdir();//创建文件夹
}
System.out.println("上传文件保存地址:" + realPath);
InputStream in = file.getInputStream();
FileOutputStream out = new FileOutputStream(new File(realPath, uploadFileName));
int len = 0;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer)) != -1){
out.write(buffer,0,len);
out.flush();
}
out.close();
in.close();
return "redirect:/index.jsp";
}
// 采用file.Transto 来保存上传的文件
@RequestMapping("/upload2")
public String fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
//上传路径保存设置
String path = request.getServletContext().getRealPath("/upload");
File realPath = new File(path);
if(!realPath.exists()){
realPath.mkdir();
}
//上传文件地址
System.out.println("上传文件地址:" + realPath);
//通过CommonsMultipartFile的方法直接写文件(注意这个时候)
file.transferTo(new File(realPath + "/" + file.getOriginalFilename()));
return "redirect:/index.jsp";
}
//文件下载
@RequestMapping(value = "/download")
public String download(HttpServletResponse response , HttpServletRequest request) throws Exception{
//要下载的图片地址
String path = request.getServletContext().getRealPath("/upload");
String fileName = "基础语法.jpg";
//1、设置response 响应头
response.reset(); //设置页面不缓存,清空buffer
response.setCharacterEncoding("UTF-8"); //字符编码
response.setContentType("multipart/form-data"); //二进制传输数据
//设置响应头
response.setHeader("Content-Disposition", "attachment;fileName="+ URLEncoder.encode(fileName, "UTF-8"));
File file = new File(path,fileName);
//2、 读取文件--输入流
InputStream input=new FileInputStream(file);
//3、 写出文件--输出流
OutputStream out = response.getOutputStream();
byte[] buff =new byte[1024];
int index=0;
//4、执行 写出操作
while((index= input.read(buff))!= -1){
out.write(buff, 0, index);
out.flush();
}
out.close();
input.close();
return null;
}
}
文件上传配置
切片上传
<!--bean的id必须为multipartResolver , 否则上传文件会报400的错误!-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->
<property name="defaultEncoding" value="utf-8"/>
<!-- 上传文件大小上限,单位为字节(10485760=10M) -->
<property name="maxUploadSize" value="10485760"/>
<property name="maxInMemorySize" value="40960"/>
</bean>
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="/upload" enctype="multipart/form-data" method="post">
<input type="file" name="file"/>
<input type="submit" value="upload">
</form>
<a href="/download">点击下载</a>
</body>
</html>