Categories
discuss

How to do a @CrossOrigin annotation in Spring 3?

I’d like to do @CrossOrigin like this:

@CrossOrigin(origins = "http://domain2.com")
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
    // ...
}

(Assuming upgrading to Spring 4 is constrained) What I have to do at the moment with Spring 3 looks like this:

public class CORSFilter implements Filter {
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request= (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
        response.setHeader("Access-Control-Expose-Headers", "x-requested-with"); chain.doFilter(req, res);
    }
}

Note that the source for the implementation of @CrossOrigin in Spring 4.2 is here.

My question is: How to do a @CrossOrigin annotation in Spring 3?

Answer

You do it like this:

package com.mycompany;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Spring3CorsFilter {}

package com.mycompany;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * The purpose of this class is to emulate the Spring 4 annotation @CORSFilter - using the power of Spring 3
 * Note that is is constrained to non-prod environments
 */
public class Spring3CorsFilterHandlerInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws
            Exception {

        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            // Test if the controller-method is annotated with @Spring3CORSFilter
            Spring3CorsFilter filter = handlerMethod.getMethod().getAnnotation(Spring3CorsFilter.class);
            if (filter != null ) {
                // ... do the filtering
                response.setHeader("Access-Control-Allow-Origin", "*");
                response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
                response.setHeader("Access-Control-Max-Age", "3600");
                response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
            }
        }
        return true;
    }
}

package com.mycompany;

import com.google.common.base.Optional;
import com.google.common.collect.FluentIterable;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.util.Arrays;
import java.util.Set;

import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertFalse;


@RunWith(SpringJUnit4ClassRunner.class)
public class Spring3CorsFilterHandlerInterceptorTest {

    @Autowired
    private RequestMappingHandlerMapping requestMappingHandlerMapping;

    @Test
    public void interceptor_is_on_request() throws Exception {
        MockHttpServletRequest request = new MockHttpServletRequest("GET",
                "/public/version");

        HandlerExecutionChain handlerExecutionChain = requestMappingHandlerMapping.getHandler(request);

        Optional<Spring3CorsFilterHandlerInterceptor> containsHandler = FluentIterable
                .from(Arrays.asList(handlerExecutionChain.getInterceptors()))
                .filter(Spring3CorsFilterHandlerInterceptor.class).first();

        // Note that this will be present for all requests due to the mapping in spring-security.xml
        assertTrue(containsHandler.isPresent());
    }

    @Test
    public void interceptor_is_not_run_on_non_annotated_request() throws Exception {
    MockHttpServletRequest request = new MockHttpServletRequest("GET",
                "/public/home");

        HandlerExecutionChain handlerExecutionChain = requestMappingHandlerMapping.getHandler(request);

        Optional<Spring3CorsFilterHandlerInterceptor> containsHandler = FluentIterable
                .from(Arrays.asList(handlerExecutionChain.getInterceptors()))
                .filter(Spring3CorsFilterHandlerInterceptor.class).first();

        MockHttpServletResponse response = new MockHttpServletResponse();

        Spring3CorsFilterHandlerInterceptor handlerInterceptor = containsHandler.get();
        handlerInterceptor.preHandle(request, response, handlerExecutionChain.getHandler());

        Set<String> headerNames = response.getHeaderNames();
        assertFalse(headerNames.contains("Access-Control-Allow-Origin"));
        assertFalse(headerNames.contains("Access-Control-Allow-Methods"));
        assertFalse(headerNames.contains("Access-Control-Max-Age"));
        assertFalse(headerNames.contains("Access-Control-Allow-Headers"));
    }

    @Test
    public void interceptor_runs_on_annotated_request() throws Exception {

        MockHttpServletRequest request = new MockHttpServletRequest("GET",
                "/public/version");
        MockHttpServletResponse response = new MockHttpServletResponse();

        HandlerExecutionChain handlerExecutionChain = requestMappingHandlerMapping.getHandler(request);

        Optional<Spring3CorsFilterHandlerInterceptor> containsHandler = FluentIterable
                .from(Arrays.asList(handlerExecutionChain.getInterceptors()))
                .filter(Spring3CorsFilterHandlerInterceptor.class).first();

        Spring3CorsFilterHandlerInterceptor handlerInterceptor = containsHandler.get();
        handlerInterceptor.preHandle(request, response, handlerExecutionChain.getHandler());

        Set<String> headerNames = response.getHeaderNames();
        assertTrue(headerNames.contains("Access-Control-Allow-Origin"));
        assertTrue(headerNames.contains("Access-Control-Allow-Methods"));
        assertTrue(headerNames.contains("Access-Control-Max-Age"));
        assertTrue(headerNames.contains("Access-Control-Allow-Headers"));
    }
}
Categories
discuss

Using reference variable to point to a Comparator?

I ran into a new way of creating Comparator while doing exercises. Can anyone explain this a little bit?

class Checker{    
    public Comparator<Player> desc = new Comparator<Player>() {
        public int compare(Player A, Player B){
            if(A.score < B.score){
                return 1;
            }
            else if(A.score == B.score){
                return B.name.compareTo(A.name);
            }
            else{
                return -1;
            }
        }
    };
}

In the past, I have only seen people doing this:

class Checker implements Comparator{
    @Override
    public int compare(Player A, Player B){
        ..........
        ..........
    }
}

So the first example really seems novel to me(because I am a beginner?). It does make sense: desc could be an property/instance variable of class Checker which points to a new instance of Comparator class/interface. However are there more stories behind these two different ways of doing things? They all require creating a different class so I don’t see how either one could be more organized.

Answer

Both the syntax are absolutely correct. In first case you are simply using concept of anonymous class. In second you created a class Checker which implements compare method.

As a beginner it is much easier to understand second syntax other than that there is no difference between the two.

You can study more about anonymous class here –

https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html

If you want to use comparator at more places its better to use solution in separate class than anonymous one. Anonymous vs class solution is something like inline css style vs style classes.

Categories
discuss

Android Studio string hello_world not present in string.xml file

I’m new to Android app development, trying to follow an intro book on the subject. After creating a blank project, I’m instructed to open the string.xml file, which is supposed to contained the element <string name="hello_world">Hello World!</string> in order to edit the default text of the TextView object. However, the file doesn’t contain this element. It only contains:

enter image description here

Also, the book only shows an activity_main.xml layout file, whereas I’m seeing both an activity_main.xml and a content_main.xml file.

Perhaps this is a version issue? My install of the Android SDK is on Windows 10 with the latest API 23, whereas I think the book was published before API 23 was released.

Answer

The default project template has probably changed since the book was written.

Try creating a new project, and when asked, choose “Empty Activity” instead of “Blank Activity”. This should only include activity_main.xml

This doesn’t include the hello_world string in the resources however, so just add it yourself by adding a line with

<string name="hello_world">Hello World!</string>

to the strings.xml

Moreover, they decided to break the convention they had been going with for the default template. There is a TextView in the activity_main.xml layout, but it uses a hardcoded string, rather than a string resource.

If you modify the text attribute of this TextView to: @string/hello_world, you should be able to mirror the desired behavior that the book is asking for.

Here’s a page straight out from the official Android docs on String resources. It may help you understand it better: https://developer.android.com/guide/topics/resources/string-resource.html

Categories
discuss

How does this pattern work: ‘test/e2e/**/*.spec.js’?

I saw this pattern used in a configuration file for protractor.

specs: [
  'test/e2e/**/*.spec.js'
]

To mean it means “all files inside test/e2e“. What kind of pattern is this? I think it’s not regex because of those unescaped slashes. Especially, why is there ** in the middle, not just test/e2e/*.spec.js?

I tried using the search engine, but did not find anything useful probably because the asterisks don’t work very well in search engines.

Answer

What kind of pattern is this?

It is called “glob“. The module glob is a popular implementation for Node, and appears to be the one used by Protractor.

Especially, why is there “**” in the middle, not just “test/e2e/*.spec.js”?

** means it can match sub-directories. It’s like a wildcard for sub-directories.

For example, test/e2e/*.spec.js would match test/e2e/example.spec.js, but not test/e2e/subdir/example.spec.js. However test/e2e/**/*.spec.js matches both.

Categories
discuss

Nested RecyclerView like Google Play Store App

I am currently working on replicating the UI pattern implemented in the Play Store App. For implementing such a behavior, I have used a Vertical RecyclerView as outer view and added a horizontal RecyclerView inside the adapter of the outer Vertical RecyclerView.

The problem I am currently facing is while the outer RecyclerView is scrolling, the inner horizontal RecyclerView cannot catch the scroll event on it, but when the outer RecyclerView is not scrolling, we can scroll the horizontal RecyclerView smoothly.

If any one can be helpful please leave your comment. Cou can test the functionality in the Play store it enables the scroll of inner horizontal RecyclerView, even if the outer RecyclerView is scrolling.

Play store app:

link to the image

Answer

Here’s a tutorial for implementing such RecyclerView. You might also consider looking at the github repository as well.

The idea is to disable the touch detection of the outer RecyclerView when the inner RecyclerView is touched. See the implementation here in the parent RecyclerView adapter class.

// Disable touch detection for parent recyclerView if we use vertical nested recyclerViews
private View.OnTouchListener mTouchListener = new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        v.getParent().requestDisallowInterceptTouchEvent(true);
        return false;
    }
}; 

And then set the touch listener to the view.

view.findViewById(R.id.recyclerView).setOnTouchListener(mTouchListener);
Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..