Tuesday, September 8, 2015

J2EE Miscs



Tomcat is not adding trailing slash to web app's context
It seems that your application's web.xml has a mapping to "/*". A servlet-mapping to "/*"causes tomcat to pass the request as-is to the web application (i.e. does not redirect).
To properly redirect, you must change the "/*" mapping to just "/", the latter means the default servlet.

<url-pattern>/*</url-pattern>

The /* on a servlet overrides all other servlets. Whatever request you fire, it will end up in that servlet. This is thus a bad URL pattern for servlets. Usually, you'd like to use /* on a Filteronly. It is able to let the request continue to any of the servlets listening on a more specific URL pattern by calling FilterChain#doFilter().

<url-pattern>/</url-pattern>

The / doesn't override any other servlet. It only replaces the servletcontainer's builtin default servlet for all requests which doesn't match any other registered servlet. This is normally only invoked on static resources (CSS/JS/image/etc) and directory listings. The servletcontainer's builtin default servlet is also capable of dealing with HTTP cache requests and file download resumes. In case of *.jsp, the servletcontainer's builtin JspServlet is being invoked, so the servlet on / won't be invoked. This is thus also a bad URL pattern for servlets. Usually, you don't want to override the default servlet as you would otherwise have to take care of all its tasks.

<url-pattern></url-pattern>

Then there's also the empty string URL pattern . This will be invoked when the context root is requested. This is different from the <welcome-file> approach that it isn't invoked when any subfolder is requested. This is most likely the URL pattern you're actually looking for in case you want a "home page servlet".
Servlet
http://javapapers.com/servlet/what-is-servlet-mapping/
A servlet container can have a internal JSP container. In such case, *.jsp extension is mapped to the internal container. This mapping is called implicit mapping. This implicit mapping allows ondemand execution of JSP pages. Servlt mapping defined in web application has high precedence over the implicit mapping.

1. The container will try to find an exact match of the path of the request to the path of the servlet. A successful match selects the servlet.
2. The container will recursively try to match the longest path-prefix. This is done by stepping down the path tree a directory at a time, using the ’/’ character as a path separator. The longest match determines the servlet selected.
3. If the last segment in the URL path contains an extension (e.g. .jsp), the servlet container will try to match a servlet that handles requests for the extension. An extension is defined as the part of the last segment after the last ’.’ character.
4. If neither of the previous three rules result in a servlet match, the container will attempt to serve content appropriate for the resource requested. If a “default” servlet is defined for the application, it will be used.
http://www.javaroots.com/2013/01/servlet-request-url-pattern-explained.html
if a servlet is mapped with url pattern '/' then it is called the default servlet 

if a servlet is mapped with empty string url pattern then it is mapped to context root of web application

getPathInfo()  provides excess path info if path matching pattern is used in finding the servlet.

http://docs.roguewave.com/hydraexpress/3.5.0/html/rwsfservletug/4-3.html
A mapping that contains the pattern <url-pattern>/</url-pattern> matches a request if no other pattern matches. This is the default mapping. The servlet mapped to this pattern is called the default servlet.
The default mapping is often directed to the first page of an application. Explicitly providing a default mapping also ensures that malformed URL requests into the application return are handled by the application rather than returning an error.

Upload file size limit
tomcat server.xml
<Connector port="80" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"
                maxPostSize="67589953" />

http://stackoverflow.com/questions/8139327/filter-for-limiting-the-file-size-on-upload-in-jersey
@Component
public class SizeLimitFilter implements ResourceFilter, ContainerRequestFilter {

    @Override
    public ContainerRequest filter(final ContainerRequest request) {
        LimitedInputStream limitedInputStream = new LimitedInputStream(request.getEntityInputStream(), 1024 * 1024 * 10) {
            @Override
            protected void raiseError(final long pSizeMax, final long pCount) throws IOException {
                // Throw error here :)
            }
        };
        request.setEntityInputStream(limitedInputStream);
        return request;
    }
}
@HeaderParam("Content-Length") int length

http://tomcat.apache.org/whichversion.html
Tomcat and servlet version

http://stackoverflow.com/questions/8139327/filter-for-limiting-the-file-size-on-upload-in-jersey
The @MultipartConfig Annotation
@MultipartConfig(
    maxFileSize=10485760,     // 10Mb max
    fileSizeThreshold=524288, //512 Kb before buffering to disk
    maxRequestSize=10240      // 10Kb of meta data
    location=/tmp             // with permission to write, default uses tomcat tmp
)
Overriding a class file from a library JAR in a Java web app
http://www.elvisyu.com/hacking-jar-file/
The answer depends upon your container, it is container dependent. In general, /WEB-INF/classes is preferred to classes in a jar file in WEB-INF/lib.
For Tomcat, the order is the following:
Therefore, from the perspective of a web application, class or resource loading looks in the following repositories, in this order:
  1. Bootstrap classes of your JVM
  2. System class loader classes
  3. /WEB-INF/classes of your web application
  4. /WEB-INF/lib/*.jar of your web application
  5. Common class loader classes
Filter
http://stackoverflow.com/questions/24497349/javax-servlet-filter-vs-jersey-filter
Whatever you decide, you will be using a javax.servlet based Filter implementation, since it is the base interface for every Filter you use in Java EE.

Now, Jersey comes with an implementation that adds some functionality (access to your ContainerRequestContext or whatever you would need inside your Jersey application).
http://stackoverflow.com/questions/686217/maximum-on-http-header-values
No, HTTP does not define any limit. However most web servers do limit size of headers they accept. For example in Apache default limit is 8KB, in IIS it's 16K. Server will return 413 Entity Too Large error if headers size exceeds that limit.

hibernate 一级和二级缓存使用总结
http://blog.csdn.net/defonds/article/details/2308972
   hibernate的缓存分为一级缓存和二级缓存,一级二级和我们常说的cpu的一级二级是不一样的。这里的一级说的是session的缓存,是hibernate内置的,不能卸载。二级说的是SessionFactory中的外置缓存,SessionFactory的内置缓存是放映射数据和sql语句的,程序不能更改,也不算二级缓存。二级缓存可以配置和更改,并且动态加载和卸载。Hibernate还为查询结果提供了一个查询缓存,它依赖于第二级缓存。 
   二. 一级缓存的管理:当应用程序调用Session的save()、update()、savaeOrUpdate()、get()或load(),以及调用查询接口的 list()、iterate()或filter()方法时,如果在Session缓存中还不存在相应的对象,Hibernate就会把该对象加入到第一级缓存中。当清理缓存时,Hibernate会根据缓存中对象的状态变化来同步更新数据库。 Session为应用程序提供了两个管理缓存的方法: evict(Object obj):从缓存中清除参数指定的持久化对象。 clear():清空缓存中所有持久化对象。 

Prevent Brute Force Authentication Attempts with Spring Security
public class AuthenticationFailureListener
  implements ApplicationListener<AuthenticationFailureBadCredentialsEvent> {
    @Autowired
    private LoginAttemptService loginAttemptService;
    public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent e) {
        WebAuthenticationDetails auth = (WebAuthenticationDetails)
          e.getAuthentication().getDetails();
         
        loginAttemptService.loginFailed(auth.getRemoteAddress());
    }
}
public class LoginAttemptService {
    private final int MAX_ATTEMPT = 10;
    private LoadingCache<String, Integer> attemptsCache;
    public LoginAttemptService() {
        super();
        attemptsCache = CacheBuilder.newBuilder().
          expireAfterWrite(1, TimeUnit.DAYS).build(new CacheLoader<String, Integer>() {
            public Integer load(String key) {
                return 0;
            }
        });
    }
    public void loginSucceeded(String key) {
        attemptsCache.invalidate(key);
    }
    public void loginFailed(String key) {
        int attempts = 0;
        try {
            attempts = attemptsCache.get(key);
        } catch (ExecutionException e) {
            attempts = 0;
        }
        attempts++;
        attemptsCache.put(key, attempts);
    }
    public boolean isBlocked(String key) {
        try {
            return attemptsCache.get(key) >= MAX_ATTEMPT;
        } catch (ExecutionException e) {
            return false;
        }
    }
}

http://blog.csdn.net/chszs/article/details/49494701
Tomcat 8启动很慢,且日志上无任何错误,在日志中查看到如下信息:
Log4j:[2015-10-29 15:47:11]  INFO ReadProperty:172 - Loading properties file from class path resource [resources/jdbc.properties]
Log4j:[2015-10-29 15:47:11]  INFO ReadProperty:172 - Loading properties file from class path resource [resources/common.properties]
29-Oct-2015 15:52:53.587 INFO [localhost-startStop-1] org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [342,445] milliseconds.

原因

Tomcat 7/8都使用org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom类产生安全随机类SecureRandom的实例作为会话ID,这里花去了342秒,也即接近6分钟。
SHA1PRNG算法是基于SHA-1算法实现且保密性较强的伪随机数生成器。
在SHA1PRNG中,有一个种子产生器,它根据配置执行各种操作。
1)如果java.security.egd属性或securerandom.source属性指定的是”file:/dev/random”或”file:/dev/urandom”,那么JVM会使用本地种子产生器NativeSeedGenerator,它会调用super()方法,即调用SeedGenerator.URLSeedGenerator(/dev/random)方法进行初始化。
2)如果java.security.egd属性或securerandom.source属性指定的是其它已存在的URL,那么会调用SeedGenerator.URLSeedGenerator(url)方法进行初始化。
这就是为什么我们设置值为”file:///dev/urandom”或者值为”file:/./dev/random”都会起作用的原因。
在这个实现中,产生器会评估熵池(entropy pool)中的噪声数量。随机数是从熵池中进行创建的。当读操作时,/dev/random设备会只返回熵池中噪声的随机字节。/dev/random非常适合那些需要非常高质量随机性的场景,比如一次性的支付或生成密钥的场景。
当熵池为空时,来自/dev/random的读操作将被阻塞,直到熵池收集到足够的环境噪声数据。这么做的目的是成为一个密码安全的伪随机数发生器,熵池要有尽可能大的输出。对于生成高质量的加密密钥或者是需要长期保护的场景,一定要这么做。
那么什么是环境噪声?
随机数产生器会手机来自设备驱动器和其它源的环境噪声数据,并放入熵池中。产生器会评估熵池中的噪声数据的数量。当熵池为空时,这个噪声数据的收集是比较花时间的。这就意味着,Tomcat在生产环境中使用熵池时,会被阻塞较长的时间。

解决

有两种解决办法:
1)在Tomcat环境中解决

可以通过配置JRE使用非阻塞的Entropy Source。

在catalina.sh中加入这么一行:-Djava.security.egd=file:/dev/./urandom 即可。
http://docs.jboss.org/hibernate/validator/5.0/reference/en-US/html_single/

    private static Validator validator;

    @BeforeClass
    public static void setUp() {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        validator = factory.getValidator();
    }


Java用WebSocket + tail命令实现Web实时日志


Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts