Spring 注解开发。
// application.xml
// 部分代码,缺省代码见前一章
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
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.xsd
">
<!-- 注解扫描 -->
<context:component-scan base-package="com.baidu.day.text"></context:component-scan>
<!-- 数据库 -->
<context:property-placeholder location="classpath*:jdbc.properties" />
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 别名 -->
<property name="typeAliasesPackage" value="com.baidu.day.text.entity" />
<!-- 读取 mapper.xml 文件 -->
<property name="mapperLocations" value="classpath*:com/baidu/day/text/mapper/*.xml" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- mapper 接口包位置 bean name 首字母小写, IEmpMapper, I开头使用全名 -->
<property name="basePackage" value="com.baidu.day.text.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<!-- 事务 -->
<!-- 配置事务管理 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 事务注解驱动 -->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
<!-- aop注解驱动 -->
<aop:aspectj-autoproxy />
</beans>
// EmpServiceImpl.java
// 事务
@Transactional()
// 默认bean id 首字母小写,相当于<bean id="empService" class="" ></bean>
@Service("empService")
//@Scope("singleton") //声明创建模式,默认为单例模式 ;@Scope("prototype")即可设置为多例模式
@Data
public class EmpServiceImpl implements IEmpService {
// 使用 byType 引入
@Autowired
// 没有指定的时候默认找属性名同名的bean id,I 开头的找全名
// @Qualifier("IEmpMapper")
private IEmpMapper empMapper;
//事务 隔离 传播 超时
// @Transactional(isolation = Isolation.SERIALIZABLE,propagation = Propagation.SUPPORTS,timeout = 100)
@Override
public List<Emp> getAll() {
return empMapper.getAll();
}
@Override
public int addEmp(Emp e) {
int tag = empMapper.addEmp(e);
// 运行时异常
// int i = 10/0;
return tag;
}
}
aop 增强需要写在单独的类里。
// MyAspect.java
@Aspect
@Component
public class MyAspect {
@Pointcut("execution(* com.baidu.day.text.service..*.*(..))")
public void aaa() {
}
// 前置增强, 引用 aaa() 上的切点表达式
@Before("aaa()")
public void beforeMethod(JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
String simpleName = joinPoint.getTarget().getClass().getSimpleName();
String name = joinPoint.getSignature().getName();
System.out.println("前置增强");
System.out.println("参数: " + Arrays.toString(args));
System.out.println("目标名: " + simpleName);
System.out.println("方法名: " + name);
System.out.println("");
}
// 后置增强
@AfterReturning(value = "aaa()",returning = "object")
public Object afterMethod(JoinPoint joinPoint, Object object) {
System.out.println("后置增强");
System.out.println("返回值:" + object);
System.out.println("");
return object;
}
@AfterThrowing(value = "aaa()", throwing = "e")
public void exceMethod(Exception e) {
System.out.println("出错了: " +e);
System.out.println("");
}
@Around("aaa()")
public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕前置");
System.out.println("");
Object proceed = joinPoint.proceed();
System.out.println("环绕后置");
System.out.println("");
return proceed;
}
}
// pom.xml
// 导入依赖 可以免去工厂的创建过程;
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
// 测试
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:application.xml")
public class IEmpMapperTest {
@Autowired
// @Qualifier("empService")
private IEmpService empService;
@Test
public void getAll() {
List<Emp> all = empService.getAll();
for (Emp emp : all) {
System.out.println(emp);
}
}
}
MVC 架构。
Model,模型,即业务模型,负责完成业务中的数据通信处理。对应项目中的 service 和 dao。
View,视图,渲染数据,生成页面。对应项目中的 Jsp。
Controller,控制器,直接对接请求,控制MVC流程,调度模型,选择视图。对应项目中的 Servlet。
工程结构。
java 工程加入webapp 模块步骤。
pom.xml 加入 war。
File ->Project Structure ->Modules -> 点击Web 加入Web Resource Directory 和 Deployment Descriptor 。
pom.xml 加入依赖。
// pom.xml
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies>
// 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">
<!-- 配置servlet -->
<servlet>
<servlet-name>mvc</servlet-name>
<!-- 相当于自己实现的 DispatcherServlet.java-->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- <servlet-mapping>-->
<!-- <servlet-name>default</servlet-name>-->
<!-- <url-pattern>*.html</url-pattern>-->
<!-- </servlet-mapping>-->
<!-- 过滤器,解决服务端接收中文乱码问题 -->
<filter>
<filter-name>encoding</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>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
// 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
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 扫描注解-->
<context:component-scan base-package="com.baidu.day.text.controller" />
<!-- 注解的驱动 -->
<mvc:annotation-driven />
<!-- 返回字符串中文乱码解决 2 -->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=utf-8</value>
<value>text/html;charset=utf-8</value>
<value>application/x-www-form-urlencoded</value>
</list>
</property>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 视图解析 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 视图前缀 -->
<property name="prefix" value="/" />
<!-- 视图后缀 -->
<property name="suffix" value=".jsp" />
</bean>
<!-- <mvc:resources mapping="/resource/**" location="/resource/" ></mvc:resources>-->
<!-- 当请求没有找到资源的时候,自动转向到tomcat的默认的servlet里面 -->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
</beans>
// User.java
@Data
public class User {
private String username;
private String password;
private Integer age;
private String sex;
private String[] hobby;
private Date hiredate;
}
// login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form method="post" action="/user/login5">
用户名:<input type="text" name="username" value="张三">
密码: <input type="text" name="password" value="123">
<input type="submit" value="提交">
</form>
</body>
</html>
服务端接收客户端发来的数据。在 web.xml 中加入过滤器解决中文乱码问题。
// UserConroller.java
// 表示这是一个 controller
@Controller
// 请求地址
@RequestMapping("/user")
public class UserConroller {
// http://localhost:8080/login.jsp
@RequestMapping("/login1")
public String login1(String username, String password) {
System.out.println(String.format("%s -- %s",username, password));
//跳转到 http://localhost:8080/index.jsp
// 在 mvc.xml 里设置 index 的前缀和后缀名
return "index";
}
@RequestMapping("/login2")
// 改变接收的字段,设置是否必传,不传就会报错
public String login2(@RequestParam(name = "username",required = true) String username,@RequestParam String password) {
System.out.println(String.format("%s -- %s",username, password));
return "index";
}
@RequestMapping("/login3")
// 以对象的属性名接收
public String login3(User user) {
System.out.println(user);
return "index";
}
// http://localhost:8080/user/login4/kkone 拿到kkone
@RequestMapping("/login4/{name}")
public String login4(@PathVariable("name") String username) {
System.out.println(username);
return "index";
}
}
如果静态资源不能访问的三种设置方法。
// 1.web.xml
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
</servlet-mapping>
// 2. mvc.xml
// 访问webapp/resource
<mvc:resources mapping="/resource/**" location="/resource/" ></mvc:resources>-->
// 3. mvc.xml
<!-- 当请求没有找到资源的时候,自动转向到tomcat的默认的servlet里面 -->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
request 作用域存储数据显示到页面上。
@Controller
@RequestMapping("/user")
public class UserConroller {
@RequestMapping("/res1")
public String res1(Map<String,Object> map) {
// request 作用域
map.put("res","这是服务器返回的 res1");
return "index";
}
@RequestMapping("/res2")
public ModelAndView res2() {
ModelAndView model = new ModelAndView();
model.addObject("res","这是服务器返回的 res2");
model.setViewName("index");
return model;
}
@RequestMapping("/res3")
public String res3(Model model) {
model.addAttribute("res","这是服务器返回的 res3");
return "index";
}
}
// index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="<%=request.getContextPath()+'/'%>">
<title>Title</title>
</head>
<body>
<h3>hello.jsp</h3>
<h4>${res}</h4>
<h4></h4>
</body>
</html>
重定向和转发。
@Controller
@RequestMapping("/user")
public class UserConroller {
// http://localhost:8080/user/jump1
@RequestMapping("/jump1")
public String jump1() {
return "forward:res3";
}
@RequestMapping("/jump2")
public String jump2() {
return "redirect:http://www.baidu.com";
}
}
服务端向客户端返回数据。
// pom.xml 里加入依赖
// jackson 对象转字符串 和一些忽略字段的注解等功能
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
// User.java
@Data
public class User {
private String username;
// 对象为null 或者 值为空 时忽略
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String password;
// 忽略这个属性
@JsonIgnore
private Integer age;
// 为null的时候忽略
@JsonInclude(JsonInclude.Include.NON_NULL)
private String sex;
private String[] hobby;
// 格式化时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date hiredate;
}
// JsonController.java
@Controller
@RequestMapping("/json")
public class JsonController {
// http://localhost:8080/json/demo1
@RequestMapping("/demo1")
@ResponseBody
public String demo1() {
return "hh";
}
// 返回字符串中文乱码解决 1
// @RequestMapping(value = "/demo2", produces = "text/plain;charset=utf-8")
@RequestMapping("/demo2")
@ResponseBody
public String demo2() {
User u = new User();
u.setUsername("张三");
ObjectMapper om = new ObjectMapper();
String s = null;
try {
// jackson 对象转字符串
s = om.writeValueAsString(u);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return s;
}
@RequestMapping("/demo3")
@ResponseBody
public User demo3() {
User user = new User();
user.setUsername("张三");
user.setPassword(new String());
user.setHiredate(new Date());
user.setHobby(new String[3]);
// 返回 json 对象
return user;
}
@RequestMapping("/demo4")
@ResponseBody
public List<User> demo4() {
List<User> list = new ArrayList<>();
for (int i = 0 ; i < 3; i ++) {
User user = new User();
user.setUsername("张三" + i);
user.setPassword("123" + i);
list.add(user);
}
// 返回 json 数组
return list;
}
}
解决返回字符串数据中文乱码的两种方法。
// 1. JsonController 方法上加注解,如上已写
// 2. mvc.xml,如上已写