[Spring实战系列]
来源:互联网 发布:华为网络机顶盒密码 编辑:程序博客网 时间:2024/06/05 05:01
本篇文章,我们继续学习《Spring实战》第四版的Spittr项目。这个项目的目的是为了构建一个类似twitter的网站,在这片文章中,我们将会讲解如何构建出这个项目,以及项目一些功能,例如注册和发消息是怎么运行的。
相比于上次的文章,我改动了一些代码,请点击这里下载。所以在这里我们会从头开始展示,但是会适当简略。下篇文章这部分不再解释。另外:本文代码来源于《Spring实战》源代码,我在此只做简化,使用maven重新构建,和运行。
1. 新建一个maven项目,方法如同上篇文章。构建完成后,布置maven项目结构,同时部署pom.xml
注意:target文件为maven生成的目标目录。项目是按照这个生成文件进行运行的。所以,如果你在下载源码后想要改动代码重新运行,只需要删除该文件夹,然后启动tomcat,该文件夹会重新生成。
配置pom.xml中的依赖:
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>spitter</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>spitter Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <!-- Generic properties --> <java.version>1.6</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <!-- Web --> <jsp.version>2.2</jsp.version> <jstl.version>1.2</jstl.version> <servlet.version>3.1.0</servlet.version> <!-- Spring --> <spring-framework.version>3.2.3.RELEASE</spring-framework.version> <!-- Hibernate / JPA --> <hibernate.version>4.2.1.Final</hibernate.version> <!-- Logging --> <logback.version>1.0.13</logback.version> <slf4j.version>1.7.5</slf4j.version> <!-- Test --> <junit.version>4.11</junit.version> </properties> <dependencies> <!-- Spring MVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring-framework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring-framework.version}</version> </dependency> <!-- Other Web dependencies --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>${jstl.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlet.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>${jsp.version}</version> <scope>provided</scope> </dependency> <!-- Spring and Transactions --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring-framework.version}</version> </dependency> <!-- Logging with SLF4J & LogBack --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> <scope>compile</scope> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> <scope>runtime</scope> </dependency> <!-- Hibernate --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>${hibernate.version}</version> </dependency> <!-- Test Artifacts --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring-framework.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <!-- Apache Commons Lang, a package of Java utility classes for the classes that are in java. --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency> <!-- Mock objects library for java --> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.10.19</version> </dependency> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>4.2.0.Final</version> </dependency> <dependency> <groupId>org.apache.tiles</groupId> <artifactId>tiles-jsp</artifactId> <version>3.0.5</version> </dependency> <!-- XML/XHTML/HTML5 template engine for Java --> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring3</artifactId> <version>2.1.4.RELEASE</version> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>2.1.4.RELEASE</version> </dependency> <!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> <version>1.3.3.RELEASE</version> </dependency> --> <!-- MySQL JDBC Type 4 driver --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> </dependencies> <build> <finalName>spitter</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.0</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.6</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </build></project>
我们依然使用注解的方式进行配置。首先新建一个webApp启动器:
package spitter.config;/** * Created by YanMing on 2017/2/26. */import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;import spitter.web.WebConfigs;public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected String[] getServletMappings() { return new String[] { "/" }; } @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[] { RootConfig.class }; } @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[] { WebConfigs.class }; }}
RootConfig 和 WebConfigs:
package spitter.config;/** * Created by YanMing on 2017/2/26. */import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.ComponentScan.Filter;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.FilterType;import org.springframework.context.annotation.Import;import org.springframework.core.type.filter.RegexPatternTypeFilter;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import spitter.config.RootConfig.WebPackage;import java.util.regex.Pattern;@Configuration@Import(DataConfig.class)@ComponentScan(basePackages={"spitter"}, excludeFilters={ @Filter(type=FilterType.CUSTOM, value=WebPackage.class) })public class RootConfig { public static class WebPackage extends RegexPatternTypeFilter { public WebPackage() { super(Pattern.compile("spittr\\.web")); } }}
package spitter.web;/** * Created by YanMing on 2017/2/26. */import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.ViewResolver;import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import org.springframework.web.servlet.view.InternalResourceViewResolver;@Configuration@EnableWebMvc@ComponentScan("spitter.web")public class WebConfigs extends WebMvcConfigurerAdapter { @Bean public ViewResolver viewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); return resolver; } @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // TODO Auto-generated method stub super.addResourceHandlers(registry); }}和前面的配置相似。WebConfigs中的内容为我们定义的视图解析器,主要的用途就是配合Controller一起寻找并加载对应视图。同时我们还重写了configureDefaultServletHandling 和 addResourceHandlers两个函数。这两个函数都是继承自WebMvcConfigurerAdapter() 。其主要功能是使用默认的servlet来处理一些跳转如"/",有兴趣的朋友点击这里Spring文档查看具体官方的解释。这里我们不再赘述。
我们需要使用数据库来存储spittles和spitter记录对吧?Yes!我们在DataConfig中配置我们的数据库:
package spitter.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.jdbc.core.JdbcOperations;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.datasource.DriverManagerDataSource;import javax.sql.DataSource;/** * Created by YanMing on 2017/2/27. */@Configurationpublic class DataConfig { @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/spring"); dataSource.setUsername("root"); dataSource.setPassword("root"); return dataSource; } @Bean public JdbcOperations jdbcTemplate(DataSource dataSource) { return new JdbcTemplate(dataSource); }}让我们来回想一下:我们把使用注解方式定义在了WebAppInitializer中,同时指定了WebConfig和RootConfig的位置。我们在WebConfig对servlet进行了配置,告诉servlet他所需要的controller都在web包中!接下来就是完善我们的Controller了!
(RootConfig书中没做太多解释,只是指明了项目基础包,同时引入了DataConfig和WebPackage)
2.创建我们的实体Spitter和Spittle(用户和消息):
package spitter;/** * Created by YanMing on 2017/2/27. */import org.apache.commons.lang3.builder.EqualsBuilder;import org.apache.commons.lang3.builder.HashCodeBuilder;import java.util.Date;public class Spittle { private final Long id; private final String message; private final Date time; private Double latitude; private Double longitude; public Spittle(String message, Date time) { this(null, message, time, null, null); } public Spittle(Long id, String message, Date time, Double longitude, Double latitude) { this.id = id; this.message = message; this.time = time; this.longitude = longitude; this.latitude = latitude; } public long getId() { return id; } public String getMessage() { return message; } public Date getTime() { return time; } public Double getLongitude() { return longitude; } public Double getLatitude() { return latitude; } @Override public boolean equals(Object that) { return EqualsBuilder.reflectionEquals(this, that, "id", "time"); } @Override public int hashCode() { return HashCodeBuilder.reflectionHashCode(this, "id", "time"); }}
package spitter;/** * Created by YanMing on 2017/2/27. */import org.apache.commons.lang3.builder.EqualsBuilder;import org.apache.commons.lang3.builder.HashCodeBuilder;import org.hibernate.validator.constraints.Email;import javax.validation.constraints.NotNull;import javax.validation.constraints.Size;public class Spitter { private Long id; @NotNull @Size(min=5, max=16) private String username; @NotNull @Size(min=5, max=25) private String password; @NotNull @Size(min=2, max=30) private String firstName; @NotNull @Size(min=2, max=30) private String lastName; @NotNull @Email private String email; public Spitter() {} public Spitter(String username, String password, String firstName, String lastName, String email) { this(null, username, password, firstName, lastName, email); } public Spitter(Long id, String username, String password, String firstName, String lastName, String email) { this.id = id; this.username = username; this.password = password; this.firstName = firstName; this.lastName = lastName; this.email = email; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public boolean equals(Object that) { return EqualsBuilder.reflectionEquals(this, that, "firstName", "lastName", "username", "password", "email"); } @Override public int hashCode() { return HashCodeBuilder.reflectionHashCode(this, "firstName", "lastName", "username", "password", "email"); }}值得一提的是,在spitter中,我们对spitter的实体使用了javax.validation相关注解。通过一些@NotNull @Size等设置了限制,告诉我们什么样的spitter是有效的。这在我们之后的注册中会起到作用。其余的部分都很简单,是对两种实体的最直白的构造。
同时,针对两种实体,我们需要编写两种接口来进行数据库操作,然后构造包含jdbctemplate对象的实体,来实现两种接口:
package spitter.data;/** * Created by YanMing on 2017/2/27. */import spitter.Spitter;public interface SpitterRepository { Spitter save(Spitter spitter); Spitter findByUsername(String username);}
package spitter.data;/** * Created by YanMing on 2017/2/27. */import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.JdbcOperations;import org.springframework.jdbc.core.RowMapper;import org.springframework.stereotype.Repository;import java.sql.ResultSet;import java.sql.SQLException;import spitter.Spitter;@Repositorypublic class JdbcSpitterRepository implements SpitterRepository { private JdbcOperations jdbc; @Autowired public JdbcSpitterRepository(JdbcOperations jdbc) { this.jdbc = jdbc; } public Spitter save(Spitter spitter) { jdbc.update( "insert into Spitter (username, password, first_name, last_name, email)" + " values (?, ?, ?, ?, ?)", spitter.getUsername(), spitter.getPassword(), spitter.getFirstName(), spitter.getLastName(), spitter.getEmail()); return spitter; // TODO: Determine value for id } public Spitter findByUsername(String username) { return jdbc.queryForObject( "select id, username, null, first_name, last_name, email from Spitter where username=?", new SpitterRowMapper(), username); } private static class SpitterRowMapper implements RowMapper<Spitter> { public Spitter mapRow(ResultSet rs, int rowNum) throws SQLException { return new Spitter( rs.getLong("id"), rs.getString("username"), null, rs.getString("first_name"), rs.getString("last_name"), rs.getString("email")); } }}
package spitter.data;/** * Created by YanMing on 2017/2/27. */import java.util.List;import spitter.Spittle;public interface SpittleRepository { List<Spittle> findRecentSpittles(); List<Spittle> findSpittles(long max, int count); Spittle findOne(long id); void save(Spittle spittle);}
package spitter.data;/** * Created by YanMing on 2017/2/27. */import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.JdbcOperations;import org.springframework.jdbc.core.RowMapper;import org.springframework.stereotype.Repository;import java.sql.ResultSet;import java.sql.SQLException;import java.util.List;import spitter.Spittle;@Repositorypublic class JdbcSpittleRepository implements SpittleRepository { private JdbcOperations jdbc; @Autowired public JdbcSpittleRepository(JdbcOperations jdbc) { this.jdbc = jdbc; } public List<Spittle> findRecentSpittles() { return jdbc.query( "select id, message, created_at, latitude, longitude" + " from Spittle" + " order by created_at desc limit 20", new SpittleRowMapper()); } public List<Spittle> findSpittles(long max, int count) { return jdbc.query( "select id, message, created_at, latitude, longitude" + " from Spittle" + " where id < ?" + " order by created_at desc limit 20", new SpittleRowMapper(), max); } public Spittle findOne(long id) { return jdbc.queryForObject( "select id, message, created_at, latitude, longitude" + " from Spittle" + " where id = ?", new SpittleRowMapper(), id); } public void save(Spittle spittle) { jdbc.update( "insert into Spittle (message, created_at, latitude, longitude)" + " values (?, ?, ?, ?)", spittle.getMessage(), spittle.getTime(), spittle.getLatitude(), spittle.getLongitude()); } private static class SpittleRowMapper implements RowMapper<Spittle> { public Spittle mapRow(ResultSet rs, int rowNum) throws SQLException { return new Spittle( rs.getLong("id"), rs.getString("message"), rs.getDate("created_at"), rs.getDouble("longitude"), rs.getDouble("latitude")); } }}这里提一下我们的@repository注解。这个非常的有用!还记得我们之前的xml配置jdbc方法么?这个注解直接将DAO实体,设置为Bean,在我们之后的Controller中可以直接使用。
2. 根据我们需要的页面编写Controller:
home.jsp:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><%@ page session="false" %><html> <head> <title>Spitter</title> <link rel="stylesheet" type="text/css" href="<c:url value="/resources/style.css" />" > </head> <body> <h1>Welcome to Spitter</h1> <a href="<c:url value="/spittles" />">Spittles</a> | <a href="<c:url value="/spitter/register" />">Register</a> </body></html>
首先需要的就是我们针对首页的HomeController:
package spitter.web;/** * Created by YanMing on 2017/2/26. */import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import static org.springframework.web.bind.annotation.RequestMethod.GET;@Controller@RequestMapping("/")public class HomeController { @RequestMapping(method = GET) public String home(Model model) { return "home"; }}
注意,要将你新建项目时候的index.jsp文件删除。否则,我们输入localhost:8080依然会默认跳转到index.jsp下。
注意到我们上面两个链接了么?一个是Spittles,一个是register。首先编写两个界面:
spittles.jsp:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><%@ taglib prefix="s" uri="http://www.springframework.org/tags"%><%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %><html> <head> <title>Spitter</title> <link rel="stylesheet" type="text/css" href="<c:url value="/resources/style.css" />" > </head> <body> <div class="spittleForm"> <h1>Spit it out...</h1> <form method="POST" name="spittleForm"> <input type="hidden" name="latitude"> <input type="hidden" name="longitude"> <textarea name="message" cols="80" rows="5"></textarea><br/> <input type="submit" value="Add" /> </form> </div> <div class="listTitle"> <h1>Recent Spittles</h1> <ul class="spittleList"> <c:forEach items="${spittleList}" var="spittle" > <li id="spittle_<c:out value="spittle.id"/>"> <div class="spittleMessage"><c:out value="${spittle.message}" /></div> <div> <span class="spittleTime"><c:out value="${spittle.time}" /></span> <span class="spittleLocation">(<c:out value="${spittle.latitude}" />, <c:out value="${spittle.longitude}" />)</span> </div> </li> </c:forEach> </ul> <c:if test="${fn:length(spittleList) gt 20}"> <hr /> <s:url value="/spittles?count=${nextCount}" var="more_url" /> <a href="${more_url}">Show more</a> </c:if> </div> </body></html>
点击Register进入registerForm.jsp:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><%@ page session="false" %><html> <head> <title>Spitter</title> <link rel="stylesheet" type="text/css" href="<c:url value="/resources/style.css" />" > </head> <body> <h1>Register</h1> <form method="POST"> First Name: <input type="text" name="firstName" /><br/> Last Name: <input type="text" name="lastName" /><br/> Email: <input type="email" name="email" /><br/> Username: <input type="text" name="username" /><br/> Password: <input type="password" name="password" /><br/> <input type="submit" value="Register" /> </form> </body></html>
package spitter.web;/** * Created by YanMing on 2017/2/27. */import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.validation.Errors;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import javax.validation.Valid;import static org.springframework.web.bind.annotation.RequestMethod.GET;import static org.springframework.web.bind.annotation.RequestMethod.POST;import spitter.Spitter;import spitter.data.SpitterRepository;@Controller@RequestMapping("/spitter")public class SpitterController { private SpitterRepository spitterRepository; @Autowired public SpitterController(SpitterRepository spitterRepository) { this.spitterRepository = spitterRepository; } @RequestMapping(value="/register", method=GET) public String showRegistrationForm() { return "registerForm"; } @RequestMapping(value="/register", method=POST) public String processRegistration( Spitter spitter, Errors errors) { if (errors.hasErrors()) { return "registerForm"; } spitterRepository.save(spitter); return "redirect:/spitter/" + spitter.getUsername(); } @RequestMapping(value="/{username}", method=GET) public String showSpitterProfile(@PathVariable String username, Model model) { Spitter spitter = spitterRepository.findByUsername(username); model.addAttribute(spitter); return "profile"; }}其中:
showRegistrationForm(),定义了我们从主页点击进入Register页面的跳转,方法为GET。
processRegistration(),定义了我们进行注册的控制:
a. 如果我们输入的信息为有效信息,调用写入数据库的save()方法,同时重定向到显示个人信息的跳转,该跳转可由
showSpitterProfile()方法获取并映射。
b. 如果我们输入的信息无效,则重新加载到该注册页面。
showSpitterProfile(),如果获取有效的用户名,则查询该用户信息,加载到model中,然后返回把信息注入profile.jsp中。
profile.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><%@ page session="false" %><html> <head> <title>Spitter</title> <link rel="stylesheet" type="text/css" href="<c:url value="/resources/style.css" />" > </head> <body> <h1>Your Profile</h1> <p>Username:<c:out value="${spitter.username}" /></p> <p>FirstName:<c:out value="${spitter.firstName}" /> LastName:<c:out value="${spitter.lastName}" /></p> <p>Email:<c:out value="${spitter.email}" /></p> </body></html>
package spitter.web;/** * Created by YanMing on 2017/2/27. */import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import java.util.Date;import java.util.List;import spitter.Spittle;import spitter.data.SpittleRepository;import spitter.web.*;@Controller@RequestMapping("/spittles")public class SpittleController { private static final String MAX_LONG_AS_STRING = "9223372036854775807"; private SpittleRepository spittleRepository; @Autowired public SpittleController(SpittleRepository spittleRepository) { this.spittleRepository = spittleRepository; } @RequestMapping(method= RequestMethod.GET) public List<Spittle> spittles( @RequestParam(value="max", defaultValue=MAX_LONG_AS_STRING) long max, @RequestParam(value="count", defaultValue="20") int count) { return spittleRepository.findSpittles(max, count); } @RequestMapping(value="/{spittleId}", method=RequestMethod.GET) public String spittle( @PathVariable("spittleId") long spittleId, Model model) { model.addAttribute(spittleRepository.findOne(spittleId)); return "spittle"; } @RequestMapping(method=RequestMethod.POST) public String saveSpittle(SpittleForm form, Model model) throws Exception { spittleRepository.save(new Spittle(null, form.getMessage(), new Date(), form.getLongitude(), form.getLatitude())); return "redirect:/spittles"; }}该Controller主要是映射我们在发布信息时候的跳转,其中:
List<Spittle> spittles()主要是我们处理首次跳转到spittles页面和每次发布消息以后的重新加载。提供了函数的默认值。调用数据库访问对象。
saveSpittle(),发出POST类型的请求,将我们的数据存入数据库。同时重定向到该页面,刷新数据(这一过程实际是发出了一个请求,该请求调用了List<Spittle> spittles(),实现了刷新)
spittle()可以处理类似“/spittles/1”这样的请求。当然我们没有什么按钮会触发这个功能。你可以直接在浏览器中输入这个跳转,查看结果。
在Spittles中使用了SpittleForm这个类.我们在输入框中输入的信息,将会在jsp中装箱成这个类的对象,然后传入saveSpittle()中,存入数据库。
spittle.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><html> <head> <title>Spitter</title> <link rel="stylesheet" type="text/css" href="<c:url value="/resources/style.css" />" > </head> <body> <div class="spittleView"> <div class="spittleMessage"><c:out value="${spittle.message}" /></div> <div> <span class="spittleTime"><c:out value="${spittle.time}" /></span> </div> </div> </body></html>
项目大概的运行流程就是这样,主要的类和功能我也都介绍完了。但是还有很多关于Spring注解内容以及jsp相关的知识我没有细讲。注解的内容我将会在下篇文章中提到。我觉得《Spring实战》这本书的例子,不妥的地方是,没有使用前后端分离的方式来讲解,而是依然使用了jsp后台注入的方式。如果以后有机会,我希望能就Spring-boot&Angular实现前后端分离,做更多的讲解。
P.S. 文章不妥之处还望指正
- Spring实战系列
- [Spring实战系列]
- [Spring实战系列]
- [Spring实战系列]
- [Spring实战系列]
- [Spring实战系列]
- [Spring实战系列]
- [Spring实战系列]
- [Spring Boot实战系列]
- [Spring实战系列]
- [Spring实战系列]
- [Spring实战系列]
- [Spring实战系列]
- [Spring Boot实战系列]
- [Spring Boot实战系列]
- [Spring Boot实战系列]
- Spring Boot实战系列教程
- 【Spring Security实战系列】Spring Security实战(一)
- Android Jni使用案例
- HDU 2859 Phalanx
- leecode 解题总结:309. Best Time to Buy and Sell Stock with Cooldown
- 字符串
- 【CodeForces】779D
- [Spring实战系列]
- 【机器学习】文本数据简单向量化
- 如何开发编译部署调用智能合约
- vue单页面开发心得
- POJ 3177(双连通分量 有重边)
- oracle data dump
- 【Android develop】【学习笔记004】构建简单的用户界面
- linux安装jdk
- 摄影通俗名词解释