本系列文章旨在记录和总结自己在Java Web开发之路上的知识点、经验、问题和思考,希望能帮助更多码农和想成为码农的人。
本文转发自头条号【普通的码农】的文章,大家可以关注一下,直接在今日头条的移动端APP中阅读。因为平台不同,会出现有些格式、图片、链接无效方面的问题,我尽量保持一致。
原文链接:
https://www.toutiao.com/i6764266772968243715/
文章目录
介绍
本篇文章给出截止到
上篇文章
之时,租房网应用的完整代码。
工程结构
POM文件
<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>house-renter</groupId>
<artifactId>house-renter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.taglibs/taglibs-standard-impl -->
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.taglibs/taglibs-standard-spec -->
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-spec</artifactId>
<version>1.2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>
Web部署描述符 – web.xml
主要是用来配置 Spring MVC 的 DispatcherServlet 。
<?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">
<display-name>house-renter</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
Spring IoC配置元数据 – dispatcher.xml
主要用来开启组件扫描、配置DataSource和JdbcTemplate这两个Bean。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="houserenter"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="jdbc:h2:~/h2db/houserenter" />
<property name="username" value="sa" />
<property name="password" value="" />
<property name="maxActive" value="20" />
<property name="initialSize" value="1" />
<property name="maxWait" value="60000" />
<property name="minIdle" value="1" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
</beans>
Java代码 – 控制器层
package houserenter.controller;
import java.io.UnsupportedEncodingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import houserenter.entity.House;
import houserenter.service.HouseService;
@Controller
public class HouseRenterController {
@Autowired
private HouseService houseService;
@GetMapping("/test.action")
@ResponseBody
public String test() {
return "hello";
}
@PostMapping("/login.action")
public ModelAndView postLogin(String userName, String password) {
//这里需要验证用户是否已经注册,省略
System.out.println("userName: " + userName + ", password: " + password);
ModelAndView mv = new ModelAndView();
//重定向到查找感兴趣房源列表的动作
mv.setViewName("redirect:houses.action?userName=" + userName);
return mv;
}
@GetMapping("/houses.action")
public ModelAndView getHouses(String userName) {
//这里需要验证用户是否登录,省略
ModelAndView mv = new ModelAndView();
//查找感兴趣房源并绑定到相应JSP页面,然后将请求转发到该页面
mv.addObject("mockHouses", houseService.findHousesInterested(userName));
mv.setViewName("houses.jsp?userName=" + userName);
return mv;
}
@GetMapping("/house-details.action")
public ModelAndView getHouseDetails(String userName, String houseId) {
// 这里需要验证用户是否登录,省略
ModelAndView mv = new ModelAndView();
//查找房源详情并绑定到相应JSP页面,然后将请求转发到该页面
mv.addObject("target", houseService.findHouseById(houseId));
mv.setViewName("house-details.jsp?userName=" + userName);
return mv;
}
@GetMapping("/house-form.action")
public ModelAndView getHouseForm(String userName, String houseId) {
// 这里需要验证用户是否登录,省略
ModelAndView mv = new ModelAndView();
//查找房源详情并绑定到相应JSP页面,然后将请求转发到该页面
mv.addObject("target", houseService.findHouseById(houseId));
mv.setViewName("house-form.jsp?userName=" + userName);
return mv;
}
@PostMapping("/house-form.action")
public ModelAndView postHouseForm(String userName, House house) throws UnsupportedEncodingException {
// 这里需要验证用户是否登录,省略
//更新指定房源的详情
houseService.updateHouseById(house);
//将请求转发到查找房源详情的动作
ModelAndView mv = new ModelAndView();
mv.setViewName("redirect:house-details.action?userName=" + userName + "&houseId=" + house.getId());
return mv;
}
}
Java代码 – 服务层
package houserenter.service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import houserenter.entity.House;
@Service
public class HouseService {
@Autowired
private JdbcTemplate jdbcTemplate;
@PostConstruct
public void generateMockHouses() {
jdbcTemplate.execute("drop table if exists house");
jdbcTemplate.execute("create table house(id varchar(20) primary key, name varchar(100), detail varchar(500))");
jdbcTemplate.update("insert into house values(?, ?, ?)", "1", "金科嘉苑3-2-1201", "详细信息");
jdbcTemplate.update("insert into house values(?, ?, ?)", "2", "万科橙9-1-501", "详细信息");
}
public List<House> findHousesInterested(String userName) {
// 这里查找该用户感兴趣的房源,省略,改为用模拟数据
return jdbcTemplate.query(
"select id,name,detail from house",
new HouseMapper());
}
public House findHouseById(String houseId) {
return jdbcTemplate.queryForObject(
"select id,name,detail from house where id = ?",
new Object[]{houseId},
new HouseMapper());
}
public void updateHouseById(House house) {
jdbcTemplate.update(
"update house set id=?, name=?, detail=? where id=?",
house.getId(), house.getName(), house.getDetail(), house.getId());
}
private static final class HouseMapper implements RowMapper<House> {
@Override
public House mapRow(ResultSet rs, int rowNum) throws SQLException {
return new House(rs.getString("id"), rs.getString("name"), rs.getString("detail"));
}
}
}
Java代码 – 实体类
package houserenter.entity;
public class House {
private String id;
private String name;
private String detail;
public House(String id, String name, String detail) {
super();
this.id = id;
this.name = name;
this.detail = detail;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
@Override
public String toString() {
return "House [id=" + id + ", name=" + name + ", detail=" + detail + "]";
}
}
静态页面 – login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>租房网 - 登录•</title>
</head>
<body>
<form action="login.action" method="post">
<label for="user_name">用户名</label><input type="text" id="user_name" name="userName" />
<label for="password">密码</label><input type="password" id="password" name="password" />
<input type="submit" value="登录•" />
</form>
</body>
</html>
JSP页面
include.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.util.List" %>
<%@ page import="houserenter.entity.House" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>租房网</title>
</head>
<body>
<h1>你好,${param.userName}!欢迎来到租房网! <a href="login.html">退出</a></h1>
<br><br>
houses.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="include.jsp"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<h6>共找到你感兴趣的房源 ${mockHouses.size()} 条</h6>
<ul>
<c:forEach var="house" items="${mockHouses}">
<li><h2><a href="house-details.action?userName=${param.userName}&houseId=${house.id}">${house.name}</a></h2></li>
</c:forEach>
</ul>
</body>
</html>
house-details.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="include.jsp"%>
<h2>${target.name}<a href="house-form.action?userName=${param.userName}&houseId=${target.id}">编辑</a></h2>
<h3>${target.detail}</h3>
<h4><a href="houses.action?userName=${param.userName}">回到列表</a></h4>
</body>
</html>
house-form.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="include.jsp"%>
<form action="house-form.action" method="post">
<input type="hidden" name="userName" value="${param.userName}"/>
<input type="hidden" name="id" value="${target.id}"/>
<label for="house_name">房源名字:</label><input type="text" id="house_name" name="name" value="${target.name}" />
<label for="house_detail">房源详细信息:</label><input type="text" id="house_detail" name="detail" value="${target.detail}" />
<input type="submit" value="提交" />
</form>
</body>
</html>