1.回顾MVC架构
MVC :模型(dao,service) 视图(jsp) 控制器(Servlet)
添加所需依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.18</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
创建一个新项目
创建一个空maven,然后创建Framework Support
2. 使用注解开发SpringMVC
2.1 确定导入依赖
2.2 确定structure都有lib的全部依赖
2.3 配置DispatchServlet
这个是SpringMVC的核心; 请求分发器,前端控制器
<!--配置DispatcherServlet,springmvc的核心,请求分发器,前端控制器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 绑定MVC配置文件-->
<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>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2.4 创建一个xml文件
2.5 编写springmvc-servlet.xml配置文件
一开始用的就是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"
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"/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean id="/hello" class="com.qiu.controller.HelloController"/>
</beans>
2.6编写HelloController
继承的接口是web底下的
需要注意的是主要就改动了业务代码和视图跳转的代码
package com.qiu.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 {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView();
String result="Hello Springmvc";
mv.addObject("msg",result);
mv.setViewName("test");
return mv;
}
}
3.注解开发SpringMVC!!!
package com.qiu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
@RequestMapping("h1")
public String hello(Model model){
model.addAttribute("msg","Hello,SpringMVC");
return "hello";
}
}
<?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容器统一管理 -->
<context:component-scan base-package="com.qiu.controller"/>
<!-- 让Spring MVC不处理静态资源: HTML、JS、CSS、图片、视频 .....-->
<mvc:default-servlet-handler />
<mvc:annotation-driven />
<!-- <mvc:annotation-driven />实现Mapping和Adapter实例注入 -->
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 后缀 -->
<property name="suffix" value=".jsp" />
</bean>
</beans>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
总结:拼接页面的名字、文件路径、以及在页面中加入msg,动态设置页面 降低耦合
4.RequestMapping解释
就是多个包名的情况下,设置好多层级的RequestMapping,最好直接在方法中直接设置好固定的 访问路径,不然测试的时候比较麻烦
5.Restful风格
还是一样使用注解,然后传入参数
原来使用的是/test?a=1&b=2 通过前端传入参数
使用Restful之后 使用@PathVariable注解 还可以在RequestMapping之中添加method 的各种方法
使用这种风格的好处在于安全,也为了更加简洁
6. 重定向和转发
如果没有配置视图解析器的情况下,可以使用以下方法来转发、重定向 如果配置了视图解析器,就只有重定向的时候在前面加上redirect:即可
7. 请求参数及数据回显
从前端可以实现传参 传入为User,必须保证属性名一一对应,否则显示为null
8.乱码问题解决
乱码问题解决的方法有几种 1.req.setEncoding……(utf-8) 2.过滤器 3 post改成get 4.spring的web配置过滤器,直接加就可以 5.检查Tomcat的server.xml文件有没有设置UTF-8格式 6.SpringMVC默认乱码解决
<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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>
通用彻底解决乱码
package com.qiu.filter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class GenericEncodingFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletRequest myrequest = new MyRequest(httpServletRequest);
response.setContentType("text/html;charset=utf-8");
chain.doFilter(myrequest, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
class MyRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;
private boolean hasEncode;
public MyRequest(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public Map getParameterMap() {
String method = request.getMethod();
if (method.equalsIgnoreCase("post")) {
try {
request.setCharacterEncoding("utf-8");
return request.getParameterMap();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else if (method.equalsIgnoreCase("get")) {
Map<String, String[]> parameterMap = request.getParameterMap();
if (!hasEncode) {
for (String parameterName : parameterMap.keySet()) {
String[] values = parameterMap.get(parameterName);
if (values != null) {
for (int i = 0; i < values.length; i++) {
try {
values[i] = new String(values[i].getBytes("ISO-8859-1"), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}
hasEncode = true;
}
return parameterMap;
}
return super.getParameterMap();
}
@Override
public String getParameter(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
if (values == null) {
return null;
}
return values[0];
}
@Override
public String[] getParameterValues(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
return values;
}
}
9.JSON(重点!!)
JSON:JavaScript Object Notation, JS对象标记
理解为,用"/"风格在前端输入,却在后端有相应的模板输入对应参数得到想要的结果
实例:1/2 后端为1+2,页面显示为3
前端JSON与js的转换
记住以下两个方法:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试</title>
<script type="text/javascript">
var user={
name:"随便",
age:15,
sex:男
};
var js=JSON.stringify(user);
console.log(js);
var a=JSON.parse(js);
console.log(a);
</script>
</head>
<body>
</body>
</html>
10.jackson的使用
10.1 使用json需要先导入依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.2.2</version>
</dependency>
10.2 配置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">
<!-- 配置DispatchServlet:这个是SpringMVC的核心;请求分发器,前端控制器-->
<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:a.xml</param-value>
</init-param>
<!-- 启动等级-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--Spring乱码过滤器-->
<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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>
10.3 配置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">
<!--扫描哪里的包-->
<context:component-scan base-package="com.qiu.pojo"/>
<!-- 让Spring MVC不处理静态资源: HTML、JS、CSS、图片、视频 .....-->
<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>
10.4 编写实体类和控制层
package com.qiu.controller;
import com.qiu.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController {
@RequestMapping("/j1")
@ResponseBody
public String json1(){
User user = new User("suibian",15,"nan");
return user.toString();
}
}
package com.qiu.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private int age;
private String sex;
}
10.5 创建jsp包,先第一次尝试不经过视图解析器
@ResponseBody//这个注解会使得不经过视图解析器 所以当我们输入/j1,就会得到不经过视图解析器的结果
10.6 第二次尝试json的ObjectMapper().writeValueAsString
主要是ObjectMapper().writeValueAsString,这几个操作,可以对应输入时间,以及多组字符串等等的格式。
第二次修改控制类尝试
@Controller
public class UserController {
@RequestMapping("/j1")
@ResponseBody
public String json1() throws JsonProcessingException {
User user = new User("suibian",15,"nan");
return new ObjectMapper().writeValueAsString(user);
}
}
这个时候还是会出现乱码(中文的时候),一下解决方案 (注意了解json的格式)
10.7 JSON乱码问题(MVC自带解决方案)
在SpringMVC-servlet.xml中加入以下代码
<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>
即使json使用中有中文测试结果也可以成功
json返回当前时间格式
package com.qiu.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.text.SimpleDateFormat;
import java.util.Date;
@RestController
public class UserController {
@RequestMapping("/j1")
public String json1() throws JsonProcessingException {
Date date = new Date();
SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return new ObjectMapper().writeValueAsString(s.format(date));
}
}
关闭时间戳也可以使用json的mapper关闭(了解即可)
使用JSON自定义时间返回对象(了解即可)
11.AOP编程(补充内容-切面编程)
简单解释:很多个东西在执行,比作很多件事情,但是你要在中间插入别的事情, 让许多件事情同步在中间做这件事情 画图!↓(不知道理解对不对,可以百度再参考~)
代码先实现四个实体,分别为 代码如下
第一步先写实体类
package com.qiu.pojo;
public interface HelloWorld {
void printHelloWorld();
void doPrint();
}
package com.qiu.pojo;
public class HelloWorldImpl1 implements HelloWorld{
@Override
public void printHelloWorld() {
System.out.println("Enter HelloWorldImpl1.printHelloWorld()");
}
@Override
public void doPrint() {
System.out.println("Enter HelloWorldImpl1.doPrint()");
}
}
package com.qiu.pojo;
public class HelloWorldImpl2 implements HelloWorld{
@Override
public void printHelloWorld() {
System.out.println("Enter HelloWorldImpl2.printHelloWorld()");
}
@Override
public void doPrint() {
System.out.println("Enter HelloWorldImpl2.doPrint()");
}
}
package com.qiu.pojo;
public class TimeHandler {
public void printTime(){
System.out.println("CurrentTime = " + System.currentTimeMillis());
}
}
第二步配置bean
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<!-- 全部设置好bean,备用,以下太多注释可以先看再删除掉比较舒服,能看的清楚-->
<bean id="helloWorldImpl1" class="com.qiu.pojo.HelloWorldImpl1" />
<bean id="helloWorldImpl2" class="com.qiu.pojo.HelloWorldImpl2" />
<bean id="timeHandler" class="com.qiu.pojo.TimeHandler" />
<aop:config>
<!-- 要插入的东西-->
<aop:aspect id="time" ref="timeHandler">
<!-- 执行哪个实体-->
<aop:pointcut id="addAllMethod" expression="execution(* com.qiu.pojo.HelloWorld.*(..))"/>
<!-- 之前和之后插入的方法-->
<aop:before method="printTime" pointcut-ref="addAllMethod" />
<aop:after method="printTime" pointcut-ref="addAllMethod" />
</aop:aspect>
</aop:config>
</beans>
最后测试(自行体会,反正就是半路插进去做事情)
import com.qiu.pojo.HelloWorld;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
HelloWorld hw1 = (HelloWorld)ctx.getBean("helloWorldImpl1");
HelloWorld hw2 = (HelloWorld)ctx.getBean("helloWorldImpl2");
hw1.printHelloWorld();
hw1.doPrint();
hw2.printHelloWorld();
hw2.doPrint();
}
}
测试结果为:
CurrentTime = 1650551677460
Enter HelloWorldImpl1.printHelloWorld()
CurrentTime = 1650551677460
CurrentTime = 1650551677461
Enter HelloWorldImpl1.doPrint()
CurrentTime = 1650551677461
CurrentTime = 1650551677462
Enter HelloWorldImpl2.printHelloWorld()
CurrentTime = 1650551677462
CurrentTime = 1650551677462
Enter HelloWorldImpl2.doPrint()
CurrentTime = 1650551677462
12. FastJSON使用
|