参考资料
Java EE开发的颠覆者 Spring Boot 实战
说明
spring mvc 的配置参考的 Java EE开发的颠覆者 Spring Boot 实战 与 ,集成hibernate参考自
iteye的代码示例很不错,所以我把他的代码放到了我的git@osc上,地址:,同样也有我本篇博客的所有代码,在spring4-mvc项目中。
要注意:
- 数据库表要自己手动创建
- tomcat最好是8.0及以上
- spring 最好是4.1.X及以上,我的是4.1.9,这主要是为了以后的spring boot
- 项目所有文件列表如下:
环境:
os : windows
ide : stsspring-tool-suite-3.7.3.RELEASE-e4.5.2-win32-x86_64
jdk : 1 .7.0_79
tomcat : 8.0.36
gradle : 2.7
database : mysql
环境搭建
关于怎样用gradle搭建spring mvc 项目,我已在上一篇博客中写明:
代码
数据库文件:
spring4mvc.sql
/*Navicat MariaDB Data TransferSource Server : localhostSource Server Version : 100113Source Host : localhost:3306Source Database : spring4mvcTarget Server Type : MariaDBTarget Server Version : 100113File Encoding : 65001Date: 2016-08-04 01:29:50*/SET FOREIGN_KEY_CHECKS=0;-- ------------------------------ Table structure for book_type-- ----------------------------DROP TABLE IF EXISTS `book_type`;CREATE TABLE `book_type` ( `id` int(11) NOT NULL AUTO_INCREMENT, `type_name` varchar(100) NOT NULL, `type_desc` varchar(255) DEFAULT '', `type_family` varchar(5) DEFAULT NULL, `type_valid` tinyint(1) NOT NULL, `version` int(11) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `type_name` (`type_name`)) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;-- ------------------------------ Records of book_type-- ----------------------------INSERT INTO `book_type` VALUES ('1', '计算机', '教育', '-', '1', '1');
配置文件
标题写的是无XML,但是只是说没有了spring的配置文件与web.xml,这已经能省很大的功夫了。一行配置都没有的项目我觉得不好
build.gradle
apply plugin: 'java'apply plugin: 'war'apply plugin: 'jetty'// JDK 7sourceCompatibility = 1.7targetCompatibility = 1.7repositories { mavenLocal() mavenCentral() jcenter()}String javaeeVersion = '7.0'String servletVersion = '3.1.0'String jstlVersion = '1.2' String springVersion = '4.1.9.RELEASE'String hibernateVersion = '4.2.21.Final'String aspectjVersion = '1.8.5' dependencies { compile 'org.slf4j:slf4j-api:1.7.12' // j2ee base //providedCompile ( 'javax:javaee-web-api:' + javaeeVersion ) providedCompile 'javax.servlet:javax.servlet-api:3.0.1' compile 'javax.servlet:jstl:1.2' // spring compile ('org.springframework:spring-context:' + springVersion) compile ('org.springframework:spring-oxm:' + springVersion) compile ('org.springframework:spring-tx:' + springVersion) compile ('org.springframework:spring-jdbc:' + springVersion) compile ('org.springframework:spring-beans:' + springVersion) compile ('org.springframework:spring-aop:' + springVersion) compile ('org.springframework:spring-test:' + springVersion) compile ('org.springframework:spring-aspects:' + springVersion) compile ('org.springframework:spring-web:' + springVersion) compile ('org.springframework:spring-core:' + springVersion) compile ('org.springframework:spring-webmvc:' + springVersion) // aspectj compile ( 'org.aspectj:aspectjrt:' + aspectjVersion ) compile ( 'org.aspectj:aspectjweaver:' + aspectjVersion ) // mysql compile ('mysql:mysql-connector-java:5.1.30') compile ('com.mchange:c3p0:0.9.2') // hibernate compile ('org.hibernate:hibernate-core:' + hibernateVersion) compile ('org.hibernate:hibernate-entitymanager:' + hibernateVersion) compile ('org.springframework:spring-orm:' + springVersion) // json compile ('org.codehaus.jackson:jackson-mapper-asl:1.9.13' ) compile ('com.google.code.gson:gson:2.2.2' ) // logback compile ('org.slf4j:jcl-over-slf4j:1.7.12') compile ('ch.qos.logback:logback-classic:1.1.3') compile ('org.logback-extensions:logback-ext-spring:0.1.2') //test testCompile 'junit:junit:4.12'}jettyRun { httpPort = 8080 contextPath = 'spring4-mvc'}//tasks.withType(Compile) { // options.encoding = "UTF-8" //}
db.properties
这个文件没有起作用,不知道怎么回事,我暂时把数据库连接的信息写在了配置代码中
jdbc.user=rootjdbc.password=rootjdbc.driverClass=com.mysql.jdbc.Driverjdbc.jdbcUrl=jdbc:mysql://localhost:3306/spring4mvc?useUnicode=true&characterEncoding=UTF-8&autoReconnect=truejdbc.initPoolSize=5jdbc.maxPoolSize=10
logback.xml
这里要注意日志的路径最好用绝对路径
UTF-8 %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n UTF-8 ${LOG_HOME}/ssh.log.%d{yyyy-MM-dd}.log 30 %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n 10MB
纯java配置取代XML配置
我的配置全放在 com.laolang.ssh.config 中
DataSourceConfig
package com.laolang.ssh.config;import java.beans.PropertyVetoException;import java.util.Properties;import javax.sql.DataSource;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.PropertySource;import org.springframework.orm.hibernate4.HibernateTransactionManager;import org.springframework.orm.hibernate4.LocalSessionFactoryBean;import com.mchange.v2.c3p0.ComboPooledDataSource;/** * 数据源和Hibernate配置 * * @author 小代码 * */@Configuration@PropertySource("classpath:db.properties")public class DataSourceConfig { @Bean public DataSource dataSource() throws PropertyVetoException { ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setUser(userName); dataSource.setPassword(passWord); dataSource.setJdbcUrl(url); dataSource.setDriverClass(driverClass); return dataSource; } @Bean public LocalSessionFactoryBean sessionFactory() throws PropertyVetoException { LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean(); sessionFactoryBean.setDataSource(dataSource()); Properties properties = new Properties(); properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect"); properties.setProperty("hibernate.show_sql", "true"); properties.setProperty("format_sql", "true"); properties.setProperty("hibernate.hbm2ddl.auto.show_sql", "update"); sessionFactoryBean.setHibernateProperties(properties); sessionFactoryBean.setPackagesToScan("com.laolang.ssh.domain"); return sessionFactoryBean; } @Bean public HibernateTransactionManager txManager() throws PropertyVetoException { HibernateTransactionManager txManager = new HibernateTransactionManager(); txManager.setSessionFactory(sessionFactory().getObject()); return txManager; } public String getDriverClass() { return driverClass; } public void setDriverClass(String driverClass) { this.driverClass = driverClass; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } 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; } @Value("com.mysql.jdbc.Driver") private String driverClass; @Value("jdbc:mysql://localhost:3306/spring4mvc?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true") private String url; @Value("root") private String userName; @Value("root") private String passWord;}
MyMvcConfig.java
package com.laolang.ssh.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;import org.springframework.transaction.annotation.EnableTransactionManagement;import org.springframework.web.servlet.HandlerMapping;import org.springframework.web.servlet.ViewResolver;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;import org.springframework.web.servlet.view.InternalResourceViewResolver;/** * spring mvc 配置类 * * @author 小代码 * @version 1.0 * */@Configuration@Import(DataSourceConfig.class)@EnableWebMvc@EnableTransactionManagement@ComponentScan("com.laolang.ssh.*")public class MyMvcConfig extends WebMvcConfigurationSupport { /** * 视图处理器 * */ @Bean public ViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".jsp"); return viewResolver; } @Bean public HandlerMapping resourceHandlerMapping() { return super.resourceHandlerMapping(); } /** * 资源访问处理器 */ @Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/assets/**").addResourceLocations("/assets/"); } }
WebInitializer
package com.laolang.ssh.config;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRegistration.Dynamic;import org.springframework.web.WebApplicationInitializer;import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;import org.springframework.web.servlet.DispatcherServlet;/** * web配置,取代web.xml * @author Administrator * */public class WebInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); context.register(MyMvcConfig.class); context.setServletContext(servletContext); Dynamic servlet = servletContext.addServlet("dispatcherServlet", new DispatcherServlet(context)); servlet.addMapping("/"); servlet.setLoadOnStartup(1); }}
实体类
BookType.java
package com.laolang.ssh.domain;import java.io.Serializable;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.Table;import javax.persistence.Version;@Entity@Table(name="book_type")public class BookType implements Serializable{ /** * */ private static final long serialVersionUID = 1L; public BookType() { super(); } public BookType(String typeName, String typeDesc, String typeFamily, boolean typeValid) { super(); this.typeName = typeName; this.typeDesc = typeDesc; this.typeFamily = typeFamily; this.typeValid = typeValid; } @Override public String toString() { return "BookType [id=" + id + ", typeName=" + typeName + ", typeDesc=" + typeDesc + ", typeFamily=" + typeFamily + ", typeValid=" + typeValid + ", version=" + version + "]"; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getTypeName() { return typeName; } public void setTypeName(String typeName) { this.typeName = typeName; } public String getTypeDesc() { return typeDesc; } public void setTypeDesc(String typeDesc) { this.typeDesc = typeDesc; } public String getTypeFamily() { return typeFamily; } public void setTypeFamily(String typeFamily) { this.typeFamily = typeFamily; } public boolean isTypeValid() { return typeValid; } public void setTypeValid(boolean typeValid) { this.typeValid = typeValid; } public Integer getVersion() { return version; } public void setVersion(Integer version) { this.version = version; } @Id @GeneratedValue private Integer id; @Column(name="type_name",unique=true) private String typeName; @Column(name="type_desc") private String typeDesc; @Column(name="type_family") private String typeFamily; @Column(name="type_valid") private boolean typeValid; @Version private Integer version;}
持久化操作
这一部分参考自 51cto 上的视频 ,iteye那篇博客中提供的封装我觉得更好。不过我打算以后用jpa,就先这么的吧
BaseService
package com.laolang.ssh.service;import java.util.List;/** * 基本CRUD接口 * * @author 小代码 * @version 1.0 * * @param* 需要持久化的实体类 */public interface BaseService { /** * 保存 * * @param t * 实体类 */ public void save(T t); /** * 更新 * * @param t * 实体类 */ public void merge(T t); /** * 根据ID删除 * * @param id * 要删除的实体类的ID */ public void delete(Integer id); /** * 通过ID查询 * * @param id * 要查询的实体的ID * @return 查询到的实体类,如果未查询到,则返回null */ public T findById(Integer id); /** * 查询所有 * * @return 查询到的实体列表 */ public List findAll(); /** * 查询所有 * * @param firstResult * 第几页 * @param maxResults * 每页记录数 * @return 查询到的实体列表 */ public List findAll(int firstResult, int maxResults); /** * 系统记录数 * * @return 记录数 */ public Long findcount(); /** * 根据每页记录数,计算共有多少页 * * @param size * 每页记录数 * @return 页数 */ public Long findpages(Integer size);}
BaseServiceImpl
package com.laolang.ssh.service.impl;import java.lang.reflect.ParameterizedType;import java.util.List;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Lazy;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import com.laolang.ssh.service.BaseService;@Transactional@Service("baseService")@Lazy(true)@SuppressWarnings("unchecked")public class BaseServiceImplimplements BaseService { @SuppressWarnings("rawtypes") public BaseServiceImpl() { ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass(); clazz = (Class) type.getActualTypeArguments()[0]; } @SuppressWarnings("rawtypes") private Class clazz; @Autowired private SessionFactory sessionFactory; protected Session getSession() { return sessionFactory.getCurrentSession(); } public void save(T t) { getSession().save(t); } public void merge(T t) { getSession().merge(t); } public void delete(Integer id) { String hql = "DELETE " + clazz.getSimpleName() + " WHERE id=:id"; getSession().createQuery(hql).setParameter("id", id).executeUpdate(); } public T findById(Integer id) { String hql = "SELECT o FROM " + clazz.getSimpleName() + " o WHERE o.id=:id"; return (T) getSession().createQuery(hql).setParameter("id", id).uniqueResult(); } public List findAll() { String hql = "FROM " + clazz.getSimpleName(); return getSession().createQuery(hql).list(); } public List findAll(int firstResult, int maxResults) { String hql = "FROM " + clazz.getSimpleName(); firstResult = ( firstResult - 1 ) * maxResults; return getSession().createQuery(hql).setFirstResult(firstResult).setMaxResults(maxResults).list(); } public Long findcount() { String hql = "SELECT COUNT(o) FROM " + clazz.getSimpleName() + " o"; return (Long) getSession().createQuery(hql).uniqueResult(); } public Long findpages(Integer size) { long count = findcount(); long pages = count / size; if ((count - pages * size) > 0) { pages += 1; } return pages; }}
BookTypeService
package com.laolang.ssh.service;import com.laolang.ssh.domain.BookType;public interface BookTypeService extends BaseService{}
BookTypeServiceImpl
package com.laolang.ssh.service.impl;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import com.laolang.ssh.domain.BookType;import com.laolang.ssh.service.BookTypeService;@Transactional@Service("bookTypeService")public class BookTypeServiceImpl extends BaseServiceImplimplements BookTypeService {}
controller
这个很简单,没什么好说的
IndexController
package com.laolang.ssh.controller;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;/** * 首页处理器,在访问首页时,做初始化工作,如初始化显示的类别 * * @author 小代码 * @version 1.0 * */@Controllerpublic class IndexController { @RequestMapping(value={"/"},method=RequestMethod.HEAD,produces="text/html") public String head(){ return "index"; } /** * * @param model * @return */ @RequestMapping(value={"/","index"},method=RequestMethod.GET,produces="text/html") public String index( Model model ){ model.addAttribute("msg", "Hello SpringMVC!"); return "index"; }}
BookTypeController
package com.laolang.ssh.controller;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;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 com.laolang.ssh.config.DataSourceConfig;import com.laolang.ssh.domain.BookType;import com.laolang.ssh.service.BookTypeService;@Controller@RequestMapping("/booktypes")public class BookTypeController { Logger log = LoggerFactory.getLogger(BookTypeController.class); @Autowired private DataSourceConfig dataSourceConfig; @Autowired private BookTypeService bookTypeService; @RequestMapping(value="booktypes",method=RequestMethod.GET,produces="text/html") public String booktypes( Model model ){ log.info("加载图书类别列表"); System.out.println(dataSourceConfig.getDriverClass()); System.out.println(dataSourceConfig.getPassWord()); System.out.println(dataSourceConfig.getUrl()); System.out.println(dataSourceConfig.getUserName()); // BookType bookType = new BookType("教育", "教育", "-", true); BookType bookType = new BookType(); bookType = bookTypeService.findById(1); bookType.setTypeName("计算机"); bookTypeService.merge(bookType); System.out.println(bookType.toString()); model.addAttribute("bookType", bookType); return "booktype/booktypes"; }}
jsp
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><% String path = request.getContextPath();%>index indexmsg:${msg }booktypes
booktypes
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><% String path = request.getContextPath();%>booktypes typeName:${bookType.typeName }typeName:${bookType.typeDesc }typeFamily:${bookType.typeFamily }typeValid:${bookType.typeValid }成功!
json 相关
- pojo
ResltPojo
package com.laolang.ssh.v1.pojo;import com.google.gson.annotations.SerializedName;public class ResultPojo { public static final Integer SUCCESS = 0; public static final Integer FAILED = -1; public ResultPojo() { super(); // TODO Auto-generated constructor stub } public ResultPojo(Integer resultCode) { this.resultCode = resultCode; if( SUCCESS == resultCode ){ this.resultDesc = "成功获取!"; } if( FAILED == resultCode ){ this.resultDesc = "获取失败!"; } } @Override public String toString() { return "ResultPojo [resultCode=" + resultCode + ", resultDesc=" + resultDesc + "]"; } public Integer getResultCode() { return resultCode; } public void setResultCode(Integer resultCode) { this.resultCode = resultCode; } public String getResultDesc() { return resultDesc; } public void setResultDesc(String resultDesc) { this.resultDesc = resultDesc; } @SerializedName("resultCode") private Integer resultCode; @SerializedName("resultDesc") private String resultDesc;}
BookTypePojo
package com.laolang.ssh.v1.pojo;import java.util.ArrayList;import java.util.List;import com.google.gson.annotations.SerializedName;import com.laolang.ssh.domain.BookType;public class BookTypePojo { public BookTypePojo() { super(); } public BookTypePojo(BookType bookType) { this.id = bookType.getId(); this.typeName = bookType.getTypeName(); this.typeDesc = bookType.getTypeDesc(); this.typeFamily = bookType.getTypeFamily(); this.typeValid = bookType.isTypeValid(); } public static ListgetBookTypePojos(List bookTypes) { List bookTypePojos = new ArrayList (); if (bookTypes.size() > 0) { for (BookType bookType : bookTypes) { bookTypePojos.add(new BookTypePojo(bookType)); } } return bookTypePojos; } @Override public String toString() { return "BookTypePojo [id=" + id + ", typeName=" + typeName + ", typeDesc=" + typeDesc + ", typeFamily=" + typeFamily + ", typeValid=" + typeValid + "]"; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getTypeName() { return typeName; } public void setTypeName(String typeName) { this.typeName = typeName; } public String getTypeDesc() { return typeDesc; } public void setTypeDesc(String typeDesc) { this.typeDesc = typeDesc; } public String getTypeFamily() { return typeFamily; } public void setTypeFamily(String typeFamily) { this.typeFamily = typeFamily; } public boolean isTypeValid() { return typeValid; } public void setTypeValid(boolean typeValid) { this.typeValid = typeValid; } @SerializedName("id") private Integer id; @SerializedName("typeName") private String typeName; @SerializedName("typeDesc") private String typeDesc; @SerializedName("typeFamily") private String typeFamily; @SerializedName("typeValid") private boolean typeValid;}
BookTypeResultPojo
package com.laolang.ssh.v1.pojo;import java.util.List;import com.google.gson.annotations.SerializedName;import com.laolang.ssh.domain.BookType;public class BookTypeResultPojo { public BookTypeResultPojo() { super(); } public BookTypeResultPojo(Integer resultCode, ListbookTypes) { this.result = new ResultPojo(resultCode); this.bookTypePojos = BookTypePojo.getBookTypePojos(bookTypes); } @Override public String toString() { return "BookTypeResultPojo [result=" + result + ", bookTypePojos=" + bookTypePojos + "]"; } public ResultPojo getResult() { return result; } public void setResult(ResultPojo result) { this.result = result; } public List getBookTypePojos() { return bookTypePojos; } public void setBookTypePojos(List bookTypePojos) { this.bookTypePojos = bookTypePojos; } @SerializedName("result") private ResultPojo result; @SerializedName("bookTypePojos") private List bookTypePojos;}
- JsonUtil
JsonUtil
package com.laolang.ssh.util;import com.google.gson.Gson;import com.google.gson.JsonNull;public class JsonUtil { public static final Gson gson = new Gson(); public static String toJson( Object o ){ if( null == o ){ return gson.toJson(JsonNull.INSTANCE); } return gson.toJson(o); }}
- v1/controller
BookTypesController
package com.laolang.ssh.v1.controller;import java.io.IOException;import java.io.PrintWriter;import java.util.List;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;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 org.springframework.web.bind.annotation.RequestParam;import com.laolang.ssh.domain.BookType;import com.laolang.ssh.service.BookTypeService;import com.laolang.ssh.util.JsonUtil;import com.laolang.ssh.v1.pojo.BookTypeResultPojo;import com.laolang.ssh.v1.pojo.ResultPojo;@Controller@RequestMapping("/v1/booktypes")public class BookTypesController { Logger log = LoggerFactory.getLogger(BookTypesController.class); @Autowired private BookTypeService bookTypeService; @RequestMapping(method = RequestMethod.POST, produces = "text/json") public String BookTypeList(@RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, Model model, HttpSession session, HttpServletResponse response, HttpServletRequest request) throws IOException { log.info("发送图书类别信息"); request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); response.setHeader("Cache-Control", "no-cache"); PrintWriter out = response.getWriter(); String jsonStr; Integer firstResult = null == page ? 1 : page; Integer maxResults = null == size ? 10 : size; ListbookTypes = bookTypeService.findAll(firstResult, maxResults); BookTypeResultPojo bookTypeResultPojo ; if( bookTypes.size() > 0 ){ bookTypeResultPojo = new BookTypeResultPojo(ResultPojo.SUCCESS, bookTypes); }else{ bookTypeResultPojo = new BookTypeResultPojo(ResultPojo.FAILED, bookTypes); } jsonStr = JsonUtil.toJson( bookTypeResultPojo ); out.print(jsonStr); out.flush(); out.close(); return null; }}
结语
最后的运行效果图就不再贴了。还有文件上传、下载,输出图片什么的,查一下资料应该不是太大问题,而且我这个项目应该会长期写下去,作为以后创建新项目的蓝本。一些最基本的分页、jquery ajax文件上传、一个相对固定的布局什么的,还是会写的
问题
- 其实我一直觉得我的spring和hibernate的集成方式有很大问题,不过秉持着 “可以运行,代码不出错就可以” 的想法,先这么写着,最近几天我得学会使用jpa了。
- 有就是前台页面的位置问题,Spring Boot 实战 这本书上说 Boot 推荐把 视图资源话在 src/main/resources 目录下,然后在配置中 /WEB-INF/views/修改为/WEB-INF/classes/views/。不过我习惯放在webapp/WEB-INF/views目录下,等到用boot的时候再说
- 前台的布局,这是个大问题,很大很大的问题