项目完工后,常用技术点小结

  1. 云栖社区>
  2. 博客>
  3. 正文

项目完工后,常用技术点小结

developerguy 2017-07-05 17:46:00 浏览1018
展开阅读全文

 

textarea placeholder 不显示

原因是textarea标签之间有空格---相当于已经设置了默认值,那placeholder就不会显示
正确的是下面这种:
<textarea name="answer" placeholder="请输入imei"></textarea>

 

jquery post方法:
html中关于csrf:

<head>
   ....
    <meta name="_csrf_parameter" th:content="${_csrf.parameterName}" content="_csrf.parameterName"/>
    <meta name="_csrf" th:content="${_csrf.token}" content="_csrf.token"/>
....
</head>

 

    $("#product").click(function () {
        var idArray = [];
        $('input[name="msgId"]').each(function () {
            idArray.push($(this).val());//向数组中添加元素
        });
        if (idArray.length > 0) {
            $.post("/msg",
                    {
                        'msgIds[]': idArray,
                        _csrf: $('meta[name=_csrf]').attr('content') //csrf
                    },
                    function (data, status) {
                        window.location.reload(); //重新加载当前页面
                    }
            );
        }

    });

http://www.w3school.com.cn/jquery/ajax_post.asp

spring mvc服务器代码:

    @PostMapping("/msg")
    @ResponseBody
    public ResponseEntity<String> markMsg(@RequestParam(value = "msgIds[]") Long[] msgIds) {
        User user = SecurityUtil.getUser();
        msgService.handle(user.getId(), msgIds);
        return ResponseEntity.ok("success");
    }


jquery post:
通过 AJAX POST 请求改变 div 元素的文本:

$("input").keyup(function(){
  txt=$("input").val();
  $.post("demo_ajax_gethint.asp",{suggest:txt},function(result){
    $("span").html(result);
  });
});

http://www.w3school.com.cn/jquery/ajax_post.asp



bootstrap 3.7.3 pull-right

            <div class="pull-right" style="border: medium fuchsia;">
                <h3>pull-right 整体右浮动 (Bootstrap),即这个外层的div整体向右浮动</h3>
                <button class="btn btn-xs" type="button">line1</button>
                <button class="btn btn-xs" type="button">line2</button>
                <button class="btn btn-xs" type="button">line3</button>
            </div>

 

hsql:
解决办法:

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)

 

严重: Servlet.service() for servlet [dispatcher] in context with path [] threw exception [Request processing failed; nested exception is org.hibernate.HibernateException: 
createCriteria is not valid without active transaction] with root cause
org.hibernate.HibernateException: createCriteria is not valid without active transaction
	at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:297)
	at com.sun.proxy.$Proxy35.createCriteria(Unknown Source)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:442)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1082)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:623)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)

 

解决办法:

Session session = getHibernateTemplate().getSessionFactory().getCurrentSession();
Transaction transaction = session.beginTransaction();
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.groupProperty("productType"));
projectionList.add(Projections.rowCount());
Criteria criteria = session.createCriteria(EquipmentInfo.class);
criteria.setProjection(projectionList);
List result = criteria.list();
transaction.commit();
System.out.println(result);
logger.info(result);
严重: Servlet.service() for servlet [dispatcher] in context with path [] threw exception [Request processing failed; nested exception is org.hibernate.HibernateException: 
createCriteria is not valid without active transaction] with root cause
org.hibernate.HibernateException: createCriteria is not valid without active transaction
	at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:297)
	at com.sun.proxy.$Proxy36.createCriteria(Unknown Source)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:442)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1082)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:623)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)

新报错:暂未解决

严重: Servlet.service() for servlet [dispatcher] in context with path [] threw exception [Request processing failed; nested exception is org.hibernate.TransactionException: JDBC commit failed] with root cause
com.atomikos.jdbc.AtomikosSQLException: Cannot call method 'commit' while a global transaction is running
	at com.atomikos.jdbc.AtomikosSQLException.throwAtomikosSQLException(AtomikosSQLException.java:46)
	at com.atomikos.jdbc.AtomikosSQLException.throwAtomikosSQLException(AtomikosSQLException.java:57)
	at com.atomikos.jdbc.AtomikosConnectionProxy.invoke(AtomikosConnectionProxy.java:129)
	at com.sun.proxy.$Proxy18.commit(Unknown Source)
	at org.hibernate.transaction.JDBCTransaction.commitAndResetAutoCommit(JDBCTransaction.java:139)
	at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:115)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:442)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1082)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:623)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)

 

编译报错:Error:(14, 22) java: 常量字符串过长

 

String内部是以char数组的形式存储,数组的长度是int类型,那么String允许的最大长度就是Integer.MAX_VALUE = 2^31 - 1 = 2147483647。
又由于java中的字符是以16位存储的,因此大概需要4GB的内存才能存储最大长度的字符串。
不过这仅仅是对字符串变量而言,如果是字符串常量,如“abc”、”1234”之类写在代码中的字符串str,那么允许的最大长度取决于字符串在常量池中的存储大小,也就是字符串在class格式文件中的存储格式:

CONSTANT_Utf8_info {
    u1 tag;
    u2 length;
    u1 bytes[length];
}

u2是无符号的16位整数,因此理论上允许的string str的最大长度是2^16-1=65535。然而实际测试表明,允许的最大长度仅为65534,超过就编译错误。

 

String str = "567890123456789...0123456789";//由于字符串长度太长,所以省略一部分,长度是65535
System.out.println(str.length());   //编译报错:Error:(14, 22) java: 常量字符串过长

 

String str = "67890123456789...0123456789";//由于字符串长度太长,所以省略一部分,长度是65534
System.out.println(str.length());   //编译通过,运行结果为:65534

 

String str = "67890123456789...0123456789";//由于字符串长度太长,所以省略一部分,长度是65534
str = "5" + str;
System.out.println(str.length());   //编译通过,运行结果为:65535

http://blog.csdn.net/xyc_csdn/article/details/72582016

mybatis配置多数据源时的报错:
解决办法:
配置文件的class-driver配置错误。将相关配置配置正确即可 

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Wed Jul 05 14:51:55 CST 2017
There was an unexpected error (type=Internal Server Error, status=500).
nested exception is org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.lang.NullPointerException ### The error may exist in class path resource [mapper/EquipmentInfoDOMapper.xml] 
### The error may involve com.domain.mapper.EquipmentInfoDOMapper.getImeiMate ### The error occurred while executing a query 
### Cause: java.lang.NullPointerException


解决办法:
在其中一个DataSource上加@Primary

Description:

The dependencies of some of the beans in the application context form a cycle:

   rtGpsController (field private com.xiaoyi.car.service.biz.StatisticsService com.xiaoyi.car.web.controller.RtGpsController.statisticsService)
      ↓
   statisticsServiceImpl (field private com.xiaoyi.car.dao.repository.CarRtGpsRepository com.xiaoyi.car.service.biz.StatisticsServiceImpl.carRtGpsRepository)
      ↓
   carRtGpsRepository (field private com.xiaoyi.car.domain.mapper.CarRtGpsDOMapper com.xiaoyi.car.dao.repository.CarRtGpsRepository.carRtGpsDOMapper)
      ↓
   carRtGpsDOMapper defined in file [E:\sns\car-statistics\car-domain\target\classes\com\xiaoyi\car\domain\mapper\CarRtGpsDOMapper.class]
      ↓
   sqlSessionFactory defined in class path resource [com/xiaoyi/car/core/config/MyBatisConfig.class]
┌─────┐
|  routingDataSource defined in class path resource [com/xiaoyi/car/core/config/MyBatisConfig.class]
↑     ↓
|  equipDataSource defined in class path resource [com/xiaoyi/car/core/config/DataSourceConfig.class]
↑     ↓
|  dataSourceInitializer
└─────┘	

 

If you need to configure multiple data sources, you can apply the same tricks that are described in the previous section. You must, however, mark one of the DataSource @Primary as various auto-configurations down the road expect to be able to get one by type.

If you create your own DataSource, the auto-configuration will back off. In the example below, we provide the exact same features set than what the auto-configuration provides on the primary data source:

@Bean
@Primary
@ConfigurationProperties("app.datasource.foo")
public DataSourceProperties fooDataSourceProperties() {
    return new DataSourceProperties();
}

@Bean
@Primary
@ConfigurationProperties("app.datasource.foo")
public DataSource fooDataSource() {
    return fooDataSourceProperties().initializeDataSourceBuilder().build();
}

@Bean
@ConfigurationProperties("app.datasource.bar")
public BasicDataSource barDataSource() {
    return (BasicDataSource) DataSourceBuilder.create()
            .type(BasicDataSource.class).build();
}

http://docs.spring.io/spring-boot/docs/1.5.4.RELEASE/reference/htmlsingle/#howto-two-datasources


Learning More:
If you want to replace the default ObjectMapper completely, either define a @Bean of that type and mark it as @Primary,
or, if you prefer the builder-based approach, define a Jackson2ObjectMapperBuilder @Bean.
Note that in either case this will disable all auto-configuration of the ObjectMapper.

Spring Boot also provides a utility builder class DataSourceBuilder that can be used to create one of the standard data sources (if it is on the classpath).
The builder can detect the one to use based on what’s available on the classpath. It also auto detects the driver based on the JDBC url.

@Bean
@ConfigurationProperties("app.datasource")
public DataSource dataSource() {
    return DataSourceBuilder.create().build();
}

To run an app with that DataSource, all that is needed really is the connection information; pool-specific settings can also be provided, check the implementation that is going to be used at runtime for more details.

app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.pool-size=30

You can fix that by forcing the connection pool to use and return a dedicated implementation rather than DataSource.
You won’t be able to change the implementation at runtime but the list of options will be explicit.

@Bean
@ConfigurationProperties("app.datasource")
public HikariDataSource dataSource() {
    return (HikariDataSource) DataSourceBuilder.create()
            .type(HikariDataSource.class).build();
}


By default Flyway will autowire the (@Primary) DataSource in your context and use that for migrations.
If you like to use a different DataSource you can create one and mark its @Bean as @FlywayDataSource - if you do that remember to create another one and mark it as @Primary if you want two data sources.
Or you can use Flyway’s native DataSource by setting flyway.[url,user,password] in external properties.

 


问题3:Bean注入失败
解决办法:使用@Qualifier指定Bean即可 
下面的例子中如果不使用@Qualifier指定Bean,则注入的两个DataSource就是使用@Primary标定的那个【现在还不清楚什么原因】

import com.xiaoyi.car.core.config.DBEnum;
import com.xiaoyi.car.core.config.DynamicDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class MyBatisConfig {

    @Bean
    public AbstractRoutingDataSource routingDataSource(@Qualifier("equipDataSource") DataSource equipDataSource,
                                                       @Qualifier("driverDataSource") DataSource driverDataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DBEnum.EQUIP, equipDataSource);
        targetDataSources.put(DBEnum.DRIVER, driverDataSource);

        AbstractRoutingDataSource routingDataSource = new DynamicDataSource();
        routingDataSource.setTargetDataSources(targetDataSources);
        routingDataSource.setDefaultTargetDataSource(equipDataSource);
        return routingDataSource;
    }

}

上面例子中使用的两个DataSource:

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {

    @ConfigurationProperties("spring.datasource.druid.equip")
    @Bean
    @Primary
    public DataSource equipDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @ConfigurationProperties("spring.datasource.druid.driver")
    @Bean
    public DataSource driverDataSource() {
        return DruidDataSourceBuilder.create().build();
    }


}

 
TODO:

需要对再加深研究,搞清楚这个路由在那种场景下会发生
org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
mybatis-spring-boot-starter的自动配置在多数据源的场景下,如何优雅的配置

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>

 



 

 

Spring mvc上传文件:
html:

<form method="POST" action="/upload" enctype="multipart/form-data">
    <input type="file" name="file" /><br/><br/>
    <input type="submit" value="Submit" />
</form>

Server:

    @PostMapping("/upload") // //new annotation since 4.3
    public String singleFileUpload(@RequestParam("file") MultipartFile file,
                                   RedirectAttributes redirectAttributes) {

        if (file.isEmpty()) {
            redirectAttributes.addFlashAttribute("message", "Please select a file to upload");
            return "redirect:upload";
        }

        try {
            // Get the file and save it somewhere
            byte[] bytes = file.getBytes();
            //如果是windows系统,则存放在服务所在目录
            // 譬如java -jar e:/upload.jar 则文件会保存在e:/tmp/目录下
            Path path = Paths.get("/tmp/" + file.getOriginalFilename());
            Files.write(path, bytes);
            System.out.println(path.toFile().getAbsolutePath());

            redirectAttributes.addFlashAttribute("message",
                    "You successfully uploaded '" + file.getOriginalFilename() + "'");

        } catch (IOException e) {
            e.printStackTrace();
        }

        return "redirect:/upload";
    }

配置文件:

# HTTP message conversion
spring.http.converters.preferred-json-mapper=jackson # Preferred JSON mapper to use for HTTP message conversion. Set to "gson" to force the use of Gson when both it and Jackson are on the classpath.

# HTTP encoding (HttpEncodingProperties)
spring.http.encoding.charset=UTF-8 # Charset of HTTP requests and responses. Added to the "Content-Type" header if not set explicitly.
spring.http.encoding.enabled=true # Enable http encoding support.
spring.http.encoding.force= # Force the encoding to the configured charset on HTTP requests and responses.
spring.http.encoding.force-request= # Force the encoding to the configured charset on HTTP requests. Defaults to true when "force" has not been specified.
spring.http.encoding.force-response= # Force the encoding to the configured charset on HTTP responses.
spring.http.encoding.mapping= # Locale to Encoding mapping.

# MULTIPART (MultipartProperties)
spring.http.multipart.enabled=true # Enable support of multi-part uploads.
spring.http.multipart.file-size-threshold=0 # Threshold after which files will be written to disk. Values can use the suffixed "MB" or "KB" to indicate a Megabyte or Kilobyte size.
spring.http.multipart.location= # Intermediate location of uploaded files.
spring.http.multipart.max-file-size=1MB # Max file size. Values can use the suffixed "MB" or "KB" to indicate a Megabyte or Kilobyte size.
spring.http.multipart.max-request-size=10MB # Max request size. Values can use the suffixed "MB" or "KB" to indicate a Megabyte or Kilobyte size.
spring.http.multipart.resolve-lazily=false # Whether to resolve the multipart request lazily at the time of file or parameter access.

 

74.5 Handling Multipart File Uploads
Spring Boot embraces the Servlet 3 javax.servlet.http.Part API to support uploading files. By default Spring Boot configures Spring MVC with a maximum file of 1MB per file and a maximum of 10MB of file data in a single request. You may override these values, as well as the location to which intermediate data is stored (e.g., to the /tmp directory) and the threshold past which data is flushed to disk by using the properties exposed in the MultipartProperties class. If you want to specify that files be unlimited, for example, set the spring.http.multipart.max-file-size property to -1.

The multipart support is helpful when you want to receive multipart encoded file data as a @RequestParam-annotated parameter of type MultipartFile in a Spring MVC controller handler method.
http://docs.spring.io/spring-boot/docs/1.5.4.RELEASE/reference/htmlsingle/#howto-multipart-file-upload-configuration


thymeleaf:
获取model的返回值前面不需要加“/",否则 会报错,找不View
redirect:"视图名前可以加/"









 

 







 








 

网友评论

登录后评论
0/500
评论
developerguy
+ 关注