周六了,趁着上午晕晕乎乎的时光写个小实例,再熟悉一下SpringMVC,为今后可能学习到的spring boot做点铺垫。不说了,直接撸代码吧。
如下是工程的结构:
首先用eclipse创建一个maven工程,然后修改一下WEB-INF下的web.xml文件,如下:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/applicationContext.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>
</web-app>
web.xml里配了servlet,contextConfigLocation是applicatoinContext.xml的位置,load-on-startup是tomcat启动时就初始化。然后是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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd" >
<context:component-scan base-package="org.test.hitest" />
<mvc:annotation-driven/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="#{config[db_driver]}"></property>
<property name="url" value="#{config[db_url]}"></property>
<property name="username" value="#{config[db_username]}"></property>
<property name="password" value="#{config[db_password]}"></property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.spatial.dialect.postgis.PostgisPG9Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>org.test.hitest.db.FileEntry</value>
</list>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="config" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:config.properties</value>
</list>
</property>
<property name="fileEncoding" value="UTF-8"></property>
</bean>
</beans>
<context:component-scan base-package="org.test.hitest" />这个配置是告诉spring去扫描这个包下的类,去注册被@Controller,@Repository等注解标注的类。
<mvc:annotation-driven/>是告诉spring去启动注解驱动,就是自动去注册上边说的Bean到工厂中。
注意,<tx:annotation-driven transaction-manager="transactionManager"/>如果不配这个事务的话,hibernate中的getCurrentSession是会报错的。
applicationContext.xml中还有有config.properties文件位置,以及hibernate的数据源一些配置。
config.properties文件如下:
db_driver=org.postgresql.Driver
db_url=jdbc:postgresql://localhost:5432/testcenter
db_username=postgres
db_password=postgres
好了,接下来就可以开始写java代码了。
我们首先来写FileEntry类吧,代码如下:
package org.test.hitest.db;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
import com.vividsolutions.jts.geom.Polygon;
@Entity
@Table(name="fileentry")
public class FileEntry {
@Id
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy="uuid")
@Column
private String id;
@Column
private String name;
@Column
private String type;
public FileEntry(){}
public FileEntry(String name, String type) {
this.name = name;
this.type = type;
}
private Polygon location;
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 getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Polygon getLocation() {
return location;
}
public void setLocation(Polygon location) {
this.location = location;
}
}
这个类中用注解的方式告诉了数据库我们要创建一个名叫fileentry的表,然后又id,name,type,以及location列。GenerateValue和GenericGenerator两个注解使得主键Id的值是由UUID生成的一个不重复唯一值。需要注意的是,由于我在表中添加了Polygon类型的location所以需要读者安装postgresql后安装postgis,然后在数据库命令行中输入如下命令:
CREATE EXTENSION postgis
这样我们创建的postgresql数据库就支持空间数据了。如果读者不想安装postgis的话,就把代码中lacation属性以及get/set方法删除就可以了。
接下来我们写FileDao类,代码如下:
package org.test.hitest.db.dao;
import java.util.logging.Logger;
import javax.transaction.Transactional;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.test.hitest.db.FileEntry;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Polygon;
@Repository
@Transactional
public class FileDao {
private static Logger logger = Logger.getLogger("com.geovis.icenter.db.FileDao");
@Autowired
private SessionFactory sessionFactory;
public String addFile(FileEntry fileEntry) {
sessionFactory.getCurrentSession().save(fileEntry);
return fileEntry.getId();
}
public String createDir(String name, String type) {
FileEntry fileEntry = new FileEntry(name, type);
return addFile(fileEntry);
}
public FileEntry queryFileById(String id) {
return sessionFactory.getCurrentSession().get(FileEntry.class, id);
}
public void addPolygonToFiles(String id, Geometry geom) {
FileEntry fileEntry = sessionFactory.getCurrentSession().get(FileEntry.class, id);
fileEntry.setLocation((Polygon)geom);
sessionFactory.getCurrentSession().update(fileEntry);
}
}
类中的@Autowired是用注解的方式去自动装配我们在applicationContext.xml中的sessionFactory类。然后类中实现了对数据库的添加以及查询的简单功能。
接下来我们下两个Response类,一个是QueryResponse,一个是SimpleResponse,代码如下:
package org.test.hitest.rest.reponse;
import org.test.hitest.db.FileEntry;
public class QueryResponse {
private int code;
private String message;
private FileEntry fileEntry;
public QueryResponse(int code, String message, FileEntry fileEntry) {
this.code = code;
this.message = message;
this.fileEntry = fileEntry;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public FileEntry getFileEntry() {
return fileEntry;
}
public void setFileEntry(FileEntry fileEntry) {
this.fileEntry = fileEntry;
}
}
package org.test.hitest.rest.reponse;
public class SimpleResponse {
private int code;
private String message;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public SimpleResponse(int code, String message) {
super();
this.code = code;
this.message = message;
}
}
这两个类是我们自己写的Response,在controller中把Response返回给用户,用户会收到一个json。同理,我们也可以写一个request,可以把浏览器(用户)传入的json由框架自动转成request类,代码如下:
package org.test.hitest.rest.request;
public class FIleCreateRequest {
private String name;
private String type;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
最后是我们的Controller类,代码如下:
package org.test.hitest.controller;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import org.test.hitest.db.FileEntry;
import org.test.hitest.db.dao.FileDao;
import org.test.hitest.rest.reponse.QueryResponse;
import org.test.hitest.rest.reponse.SimpleResponse;
import org.test.hitest.rest.request.FIleCreateRequest;
@RestController
public class DirController {
private static Logger logger = Logger.getLogger("org.test.hitest.controller.DirController");
@Autowired
private FileDao fileDao;
@RequestMapping(value="/rest/dir/query",method=RequestMethod.GET,produces="application/json")
public QueryResponse queryInfo(
@RequestParam("id") String id
){
FileEntry fileEntry = fileDao.queryFileById(id);
return new QueryResponse(0, "succ", fileEntry);
}
@RequestMapping(value="/rest/dir/create",method=RequestMethod.POST,produces="application/json")
public SimpleResponse createFile(
@RequestBody FIleCreateRequest request) {
fileDao.createDir(request.getName(), request.getType());
return new SimpleResponse(0, "success");
}
}
@RestController注解告诉spring这是Controller类,@RequestMapping注解配置了该方法对应的url以及http请求的方法,@RequestBody告诉Spring把收到的json转成我们自己的request类。我们可以简单的看一下效果(get方法直接用浏览器发送请求,post方法是用postman测试的):
下面是代码下载的链接:
https://download.csdn.net/download/u014627099/10394132