BlobStore - display photo error - blobstore

I have experience with GWT/GAE MySQL cloud. But I don’t with BlobStore. I have to add to my project photos. To understand BlobStore I found an example: https://github.com/ikai/gwt-gae-image-gallery. But it doesn’t work. I have 2 problems:
1.Why the servlet “UploadServlet” return null as a blob key:
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
// Take uploaded image
Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(req);
System.out.println("UPL.SERV.key size=" + blobs.size());
List<BlobKey> blobKey = blobs.get("image");
ImagesService imagesService = ImagesServiceFactory.getImagesService();
String imageUrl = imagesService.getServingUrl(ServingUrlOptions.Builder.withBlobKey(blobKey.get(0))).trim();
// Uploaded image object: key, servingUrl,createdAt, ownerId
Entity uploadedImage = new Entity("UploadedImage");
uploadedImage.setProperty("blobKey", blobKey.get(0).getKeyString().trim());
uploadedImage.setProperty(UploadedImage.CREATED_AT, new Date());
uploadedImage.setProperty(UploadedImage.OWNER_ID, "anna");
// Highly unlikely we'll ever search on this property
uploadedImage.setUnindexedProperty(UploadedImage.SERVING_URL, imageUrl);
System.out.println("UPL.SERV-5- Z datastore key=" + keyString);
res.sendRedirect("/upload?uploadedImageKey=" + keyString);
}
doPost redirect :
UPL.SERV-5- key=aglub19hcHBfaWRyGgsSDVVwbG9hZGVkSW1hZ2UYgICAgICA4ggM
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("UPL.SERV-6- req="+req.getParameter("uploadedImageKey"));
String uploadedImageKey = req.getParameter("uploadedImageKey").trim();
resp.setHeader("Content-Type", "text/html");
// This is a bit hacky, but it'll work. We'll use this key in an Async
// service to
// fetch the image and image information
System.out.println("UPL.SERV-7- resp="+uploadedImageKey);
resp.getWriter().println(uploadedImageKey);
}
doGet gets :
UPL.SERV-6- req=aglub19hcHBfaWRyGgsSDVVwbG9hZGVkSW1hZ2UYgICAgICA4ggM
And send answer to “UploadPhoto”:
UPL.SERV-7- resp=aglub19hcHBfaWRyGgsSDVVwbG9hZGVkSW1hZ2UYgICAgICA4ggM
“UploadPhoto gets null.
Why I can’t to display my photo?
In datastore exists:
UPL.SERV-3- SET for datastore
UPL.SERV-3-blobkey=7cvGUXW_q9Q9QTEArWv3LA
UPL.SERV-3-key=UploadedImage(no-id-yet)
UPL.SERV-3-owner=anna
UPL.SERV-3-url=http://0.0.0.0:8888/_ah/img/7cvGUXW_q9Q9QTEArWv3LA
UPL.SERV-4- put to datastore
When the widget with is created “ImageOverlay” I get:
7cvGUXW_q9Q9QTEArWv3LA=s200:1 GET http://0.0.0.0:8888/_ah/img/7cvGUXW_q9Q9QTEArWv3LA=s200 net::ERR_ADDRESS_INVALID

It doesn't work because doGet in development mode return null.

Related

Keycloak custom attribute not fetched in the claims

I am trying to fetch a custom attribute (phone_number) in the form of a claim from Keycloak. I am following the steps given here. Below are attached screenprints of the steps I have executed.
Adding attribute to user
Protocol mapper
Protocol mapper is available in Client scope -> evaluate for the above-mentioned client
I am now trying to access this attribute in a filter as follows.
public class FilterTest extends OncePerRequestFilter {
public static final String PHONE_NUMBER = "phone_number";
public FilterTest() {
}
#Override
protected void doFilterInternal(
final HttpServletRequest request,
final HttpServletResponse response,
final FilterChain filterChain) throws ServletException, IOException {
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if( !AnonymousAuthenticationToken.class.isAssignableFrom(authentication.getClass()) ){
Principal principal = (Principal) authentication.getPrincipal();
if (principal instanceof KeycloakPrincipal) {
KeycloakPrincipal<KeycloakSecurityContext> kp = (KeycloakPrincipal<KeycloakSecurityContext>) principal;
AccessToken token = kp.getKeycloakSecurityContext().getToken();
Map<String, Object> otherClaims = token.getOtherClaims();
System.out.println("Phone number => "+otherClaims.get(PHONE_NUMBER); // null pointer
}
}
filterChain.doFilter(request, response);
}
}
Additional things that I have tried.
Clear the realm cache.
Add the built-in phone number protocol mapper.
The above two steps also didn't yield any results for me.
I am not sure what I am missing here. Any help is appreciated.
Keycloak is mapping some of the common fields from the custom attributes directly to the fields of IDToken class. In my case, phone number was a field in the IDToken class and I was trying to fetch it from otherClaims map. The following is the change in code snip that got me up and running.
AccessToken token = kp.getKeycloakSecurityContext().getToken();
phoneNumber = token.getPhoneNumber();

How to get data from a void returning get request in spring?

A micro-service is providing an api(get request) to download a file which is having a return type as void. It is populating HttpServletResponse but not returning it. How can I get the data from such api?
#GetMapping(value="/download/{id}")
public void download(#PathVariable(value = "id") String id, HttpServletResponse response) {
FileDTO file = downloadFile(id, response);
response.setContentType("text/html");
....
....
}
How can we get the html/text data from the above sample snippet? (Assume all required parameters are set.)

Spring interceptor intercepting late

Spring boot 2.1.7 running a test server -- need to check my cache for a hit using the url as key, and then act based on a cache hit or not.
I send a request from my browser for https://localhost:8443/test/param=value --- my filter picks it up, and using code from another answer on SO, the filter constructs the url -- the filter code sees the url is https://localhost:8443/test?param=value
Great!
Then my interceptor gets hit (thanks to Theo on SO), but it thinks the url is https://localhost:8443/favicon.ico -- what's up with that? Not much of an interceptor if I didn't get to intercept the original /test url.
To get around that, in the filter, I stored the "real" url in the ServletContext, and that variable is read out correctly in the interceptor. Seems like an awful hack, and silly that I have to do it. For now I've hard-coded the decision to redirect to url /test2, but back in Chrome, I see the output from test1, not test2.
The network tab in Chrome seems to suggest:
that I was redirected to test2, but only after a request for favicon got inserted (for whatever mysterious reason) and yet as the image shows, the output is clearly test1, not test2.
Something I don't understand is that devtools also shows a response from test2:
#WebFilter( urlPatterns = "/test", description = "a filter for test servlet", initParams = {
#WebInitParam( name = "msg", value = "==> " ) }, filterName = "test filter" )
public class TestFilter implements Filter
{
private FilterConfig filterConfig;
#Override
public void doFilter( ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain )
throws IOException, ServletException
{
String url = getCurrentUrlFromRequest( servletRequest );
// in the debugger, url is correctly shown as
// https://localhost:8443/test/param=value
if ( null != url )
{
ServletContext s = servletRequest.getServletContext();
s.setAttribute( "realUrl", url );
}
servletResponse.getOutputStream().print( filterConfig.getInitParameter( "msg" ) );
filterChain.doFilter( servletRequest, servletResponse );
public String getCurrentUrlFromRequest( ServletRequest request )
{
if ( !( request instanceof HttpServletRequest ) ) return null;
return getCurrentUrlFromRequest( (HttpServletRequest) request );
}
public String getCurrentUrlFromRequest( HttpServletRequest request )
{
StringBuffer requestURL = request.getRequestURL();
String queryString = request.getQueryString();
if ( queryString == null ) return requestURL.toString();
return requestURL.append( '?' ).append( queryString ).toString();
}
#Override
public void destroy()
{
}
#Override
public void init( FilterConfig filterConfig ) throws ServletException
{
this.filterConfig = filterConfig;
}
}
//then the interceptor:
#Component
public class CheckForCacheInterceptor implements HandlerInterceptor
{
#Bean
public MappedInterceptor myInterceptor()
{
CheckForCacheInterceptor ci = new CheckForCacheInterceptor();
ci.setRedirectMapping( "/test2" );
return new MappedInterceptor( null, ci );
}
private String redirectMapping;
#Override
public boolean preHandle( HttpServletRequest request, HttpServletResponse response, Object handler )
{
String url = (String) request.getServletContext().getAttribute( "realUrl" );
// "realUrl" has https://localhost:8443/test/param=value, but I'd like
// to get rid of hack. Problem is that right here, running the same
// exact code (copy/paste of filter's
// getCurrentUrlFromRequest( HttpServletRequest request ) method )
//which gets the correct url in the filter yields
// https://localhost:8443/favicon.ico -- where did that come from?
// TODO check cache using requestUrl as key
boolean foundInCache = false;
if ( foundInCache )
{
// TODO: somehow write cache value to response
// then send response
return false;
} else
{
try
{
// TODO: make direct request,
// get response body, then
response.sendRedirect( redirectMapping );
return false;
} catch ( IOException e )
{
e.printStackTrace();
}
}
return false;
}
So before my questions pile up to the ceiling, I'll ask for help -- how is this favicon request sneaking in before my interceptor even has a crack at the original url, why can't I get the original url in my interceptor, and given that the Chrome devtools shows I am getting through to test2, how is the output coming from the test1 servlet instead of the test2 servlet?
FWIW, I'm getting the exact same behavior in Postman. Thanks so much for any help!
I read another answer on SO (sorry I don't have the link) which has fixed the issue of not intercepting the initial get request to /test -- it said that interceptors only intercept requests going to Controllers, so I needed to have a Controller which was mapped to /test. After writing a quickie Controller, the interceptor is now intercepting as one might expect.

Media Type not acceptable exception when using SseEmitter

Following this tutorial, I am trying to set up a Sse Emitter. When I open the html page I get a
Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation]
On client side (javascript) it sais it cannot connect to the server. I have tried various other tutorials, but I am clueless on why my code isnt working.
I set up a clean test project containing only and exactly the tutorial code.
I Was in the middle of doing something else when I got the same issue.
The code below fixed it.
Simply put Mismatch Media type.
#GetMapping(value = "/api/push/notification",headers = "Accept=*/*", consumes = MediaType.ALL_VALUE, produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public String doNotify(#RequestParam("authToken") String token, #RequestParam("clientId") String clientId, HttpServletResponse response) throws InterruptedException, IOException {
response.addHeader("charset","UTF-8");
final SseEmitter emitter = new SseEmitter(30000l);
service.addEmitter(clientId,emitter);
service.sendConnectedNotification(clientId);
emitter.onCompletion(() -> service.removeEmitter(clientId));
emitter.onTimeout(() -> service.removeEmitter(clientId));
return "Connected OK";
}
any my event handler
#Async
public void doNotify(String clientId, Object data) {
SseEmitter emitter= emitters.get(clientId);
if(emitter!=null) {
try {
emitter .send(SseEmitter.event() .reconnectTime(30000)
.data(data,MediaType.APPLICATION_JSON)
.id(UUID.randomUUID().toString())
.name("Notification")
.comment("Client connection notification")
);
} catch (Exception e) {
emitters.remove(clientId);
}
}
}

Download A File On click of a link using spring mvc

When I click on any link the content should be downloaded
But this is what I get.
MastercourseController.java
#RequestMapping(value = { ControllerUriConstant.download_file }, method = RequestMethod.GET)
#ResponseBody
public void downloadingAFileById(#RequestParam("id") String id, Model model, HttpServletRequest request)
throws TechnoShineException, IOException {
String filePath = "D:/dev/testFIle.txt";
long download = Long.parseLong(id);
byte[] b = masterCourseFileFormService.getAllDownloadable(download);
OutputStream outputStream = new FileOutputStream(filePath);
outputStream.write(b);
outputStream.close();
}
MasterCourseService
public byte[] getAllDownloadable(long id) throws TechnoShineException
{
return masterCourseFormUploadDao.getAllDownloadableFiles(id);
}
MasterCourseDao
public byte[] getAllDownloadableFiles(long id) throws TechnoShineException
{
return masterCourseFormUploadMapper.getAllDownloadable(id);
}
MasterCourseMapper
public byte[] getAllDownloadable(long id) throws TechnoShineException;
You are writing the data returned by getAllDownloadable(..) to a hard-coded file. Are you sure that is what you want? I think you want to write the content returned by getAllDownloadable(..) to be written into the response. That can be done by adding a method parameter of the type HttpServletResponse to your mapping and writing into the output stream returned by HttpServletResponse#getOutputStream() and flushing (not closing!) that stream at the end.
Furthermore you have to remove the #ResponseBody annotation as this is meant to be used if the value that is returned by the mapping method returns the data that should directly be sent to the client (i.e. when sending a JSON data object or a string) without passing it to the template engine. As you are not returning anything you can remove this annotation.
Furthermore you have to set the content type of your response by invoking HttpServletResponse#setContentType(contentType: String).
In your case, the invocation would be the following:
response.setContentType("text/plain");
You complete method would look like this:
#RequestMapping(
value = ControllerUriConstant.download_file,
method = RequestMethod.GET
)
public void downloadingAFileById(#RequestParam("id") String id, HttpServletResponse response)
throws TechnoShineException, IOException {
long download = Long.parseLong(id);
byte[] b = masterCourseFileFormService.getAllDownloadable(download);
response.getOutputStream().write(b);
response.getOutputStream().flush();
}

Resources