HttpServletRequest.getRemoteAddr() is null in rest resource - rest

I have a backend REST application running in glassfish 4.1.
In this simple test resource I want to log the remote address:
import java.util.logging.Logger;
import javax.enterprise.context.RequestScoped;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
#Path("test")
#RequestScoped
public class TestResource {
private static final Logger LOG = Logger.getLogger(TestResource.class.getName());
#Context
private UriInfo context;
public TestResource() {
}
#GET
#Produces(MediaType.TEXT_PLAIN)
public String getText(#Context HttpServletRequest req) {
LOG.info("TEST - REMOTE ADDRESS: " + req.getRemoteAddr());
throw new UnsupportedOperationException();
}
}
I have nothing "strange" and no proxy (so no "x-forwarded-for" and so on), but when I access the resource I always get null as remote address.
I have googled a lot and tried different solutions with no luck (ie: implementing a filter doesn't work: inside the filter request.getRemoteAddr() is always null).

Related

spring restfull service request and response as Text/plan

I'm new in Spring boot, I just follow a simple tutorial and I finished a simple service where I received a Json request and Response with a Json as well, now I need to change the request/response as a Text/Plain, these its what I have in my controller class:
package com.notas.core.controller;
import java.util.List;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.notas.core.entity.Nota;
import com.notas.core.model.MNota;
import com.notas.core.service.NotaService;
#RestController
#RequestMapping("/v1")
public class NotaController {
#Autowired
#Qualifier("servicio")
NotaService servicio;
#PutMapping("/nota")
public boolean agregarNota(#RequestBody #Valid Nota nota) {
return servicio.crear(nota);
}
#PostMapping("/nota")
public boolean modificarNota(#RequestBody #Valid Nota nota) {
return servicio.actualizar(nota);
}
#DeleteMapping("/nota/{id}/{nombre}")
public boolean borrarNota(#PathVariable("id") long id, #PathVariable("nombre") String nombre) {
return servicio.borrar(nombre, id);
}
#GetMapping("/notas")
public List<MNota> obtenerNotas(Pageable pageable){
return servicio.obtenerPorPaginacion(pageable);
}
}
Could you please tell me whats do I have to change in order to receive a Text/Plain and response with the same mediatype.
In all Mapping annotation (#Get, #Post...) they have an attribute consumes and produces, you could add that using the media type
#PostMapping(value="/foo", consumes = MediaType.TEXT_PLAIN_VALUE , produces= MediaType.TEXT_PLAIN_VALUE)
public String plainValue(#RequestBody String data) {
return; //logic
}

How to use Rest Service while using Spring Boot & Spring Data Jpa

Im working on a spring boot application for rest service with using spring data jpa. I followed instructors and read much answers but I couldn't fix my rest service.
Here is application.class
package tr.kasim.Application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication
#EnableJpaRepositories("tr.kasim.Dao")
#EntityScan("tr.kasim.Model")
#ComponentScan({"tr.kasim.Service", "tr.kasim.Application" })
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Here is `restcontroller.class
package tr.kasim.Controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import tr.kasim.Service.PersonelService;
import tr.kasim.Model.Personel;
#RestController
public class STRestController {
#Autowired
public PersonelService personelService;
#RequestMapping(value = "/api/personels", method = RequestMethod.GET)
public ResponseEntity<List<Personel>> getPersonels(){
List<Personel> personels = personelService.findAll();
return ResponseEntity.ok().body(personels);
}
}
`
Here is Service.class`
package tr.kasim.Service;
import java.util.List;
import tr.kasim.Model.Personel;
public interface PersonelService {
List<Personel> findAll();
}
`
Here is ServiceImplemantion.class
package tr.kasim.Service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tr.kasim.Dao.PersonelDao;
import tr.kasim.Model.Personel;
#Service
public class PersonelServiceImpl implements PersonelService {
#Autowired
private PersonelDao personelDao;
#Override
#Transactional
public List<Personel> findAll() {
return personelDao.findAll();
}
}
Here is Dao.class
package tr.kasim.Dao;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import tr.kasim.Model.Personel;
#Repository
public interface PersonelDao extends JpaRepository<Personel, Long> {
List<Personel> findAll();
}
Lastly here is my application.properties
#MySql Connection
spring.datasource.url=jdbc:mysql://localhost:3306/exampleproject?verifyServerCertificate=false&useSSL=true
spring.datasource.username=root
spring.datasource.password=*******
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#Jpa/Hibernate
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
#Logging
logging.file=staffTracking.log
logging.level.org.springframework.web=debug
Im not sure about componentScan. When I read answers I discovered someone mentioned about it but I tried and I got still nothing. Please show me where I failed. Best Regards.
I updated Application.class, now I can deploying project but rest service not working still.
How did you try ComponentScan? The issue here seems that you have a package structure like this:
tr.kasim.Application
- Application.java
tr.kasim.Service
- PersonelService.java
- PersonelServiceImpl.java
tr.kasim.Dao
- PersonelDao.java
Now since, the mainClass is in tr.kasim.Application it would scan for bean definitions inside that package (or a sub-package in tr.kasim.Application). So,
either you move the mainClass out to a parent-package like tr.kasim, or
use #ComponentScan({ "tr.kasim.Dao", "tr.kasim.Service", "tr.kasim.Application" }) and so on.
-- Update --
Based on the discussion so far, I'd suggest taking the first option as that reduces the effort to manually enable scan for entity, repository, etc.

Will Spring Mail module be alternate to javax.mail

I have a Spring boot application where I need to send an alert mail to both a gmail account and a Zoho account. I try to use Javax.mail, where I set the properties of a both Gmail and a Zoho account using Java class and use it. Will Spring mail be a best replacement for Javax.mail. I have a doubt if Spring mail module can be used because we set the SMTP server properties in application.yml
The first thing to do is to import the dependency from Maven Central Repository.
<dependency>
<groupId>it.ozimov</groupId>
<artifactId>spring-boot-email-core</artifactId>
<version>0.5.0</version>
</dependency>
Then, you populate the application.yml with the following entries
spring.mail.host: smtp.gmail.com
spring.mail.port: 587
spring.mail.username: hari.seldon#gmail.com
spring.mail.password: Th3MuleWh0
spring.mail.properties.mail.smtp.auth: true
spring.mail.properties.mail.smtp.starttls.enable: true
spring.mail.properties.mail.smtp.starttls.required: true
Now, for the sake of the example, assume that you have a service that sends a very simple plain text email. It will be something like:
package com.test;
import com.google.common.collect.Lists;
import it.ozimov.springboot.mail.model.Email;
import it.ozimov.springboot.mail.model.defaultimpl.DefaultEmail;
import it.ozimov.springboot.mail.service.EmailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.mail.internet.InternetAddress;
import java.io.UnsupportedEncodingException;
import static com.google.common.collect.Lists.newArrayList;
#Service
public class TestService {
#Autowired
private EmailService emailService;
public void sendEmail() throws UnsupportedEncodingException {
final Email email = DefaultEmail.builder()
.from(new InternetAddress("hari.seldon#the-foundation.gal",
"Hari Seldon"))
.to(newArrayList(
new InternetAddress("the-real-cleon#trantor.gov",
"Cleon I")))
.subject("You shall die! It's not me, it's Psychohistory")
.body("Hello Planet!")
.encoding("UTF-8").build();
emailService.send(email);
}
}
Let's do it in the main application, where we'll send the email just after starting and initialising the Spring context.
package com.test;
import it.ozimov.springboot.mail.configuration.EnableEmailTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.batch.JobExecutionExitCodeGenerator;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import javax.annotation.PostConstruct;
import java.io.UnsupportedEncodingException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
#SpringBootApplication
#EnableEmailTools
public class PlainTextApplication {
#Autowired
private TestService testService;
public static void main(String[] args) {
SpringApplication.run(PlainTextApplication.class, args);
}
#PostConstruct
public void sendEmail() throws UnsupportedEncodingException, InterruptedException {
testService.sendEmail();
}
}
Observe that to enable the Email Tools you need to annotate the main app with the annotation
#EnableEmailTools
that will trigger the configuration class for the extension.

Not finding repository class in spring integration test

The methods : findAll(),save(O o), findOne(long id) of interface
Repository is not found in my spring jpa integration test.
package source;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import category.IntegrationTest;
import domain.BankAccount;
import presentation.MessageContext;
import repository.BankAccountRepository;
#RunWith(SpringRunner.class)
#Category(IntegrationTest.class)
#DataJpaTest
public class BankAccountTest {
#Autowired
private BankAccountRepository repository;
#Test
public void should_find_no_customers_if_repository_is_empty() {
Iterable<BankAccount> accounts = repository.findAll();
assertNull(accounts);
}
#Test
public void shuldCreateBankAccount() {
BankAccount accounts = new BankAccount(100);
repository.save(accounts);
BankAccount accountr = repository.findOne(1l);
assertNotNull(accountr);
}
}
The repository interface looks like this
package repository;
import org.springframework.data.repository.Repository;
import domain.BankAccount;
public interface BankAccountRepository extends Repository<BankAccount, Long> {}
I have also implemeneted a configuration file
package repository;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#Configuration
#EnableJpaRepositories
public class PersistentContext {}
the classes is placed like this
Component structure
What must i to compile the code without errors?
interface Repository is empty interface ,it's common interface for spring data repositories . There is no any method , see Repository API .
If you need method findAll(),save(O o), findOne(long id) you need use CrudRepository - it's sub interface for interface Repository , or you can use JpaRepository - it's extension of CrudRepository.

#PathParam is Null

I've been looking at this for two hours, but I don't see how the batchid variable can be coming up as "" (empty String rather than null) in the debugger.
I have tried removing the #Produces/#Consumes annotations, but no luck.
I am using a linux command line POST that looks like this:
http POST http://localhost:8080/cr/feed/send-batch/550f9ef7-b586-4029-bf7d-4d0659a08707
Can someone spot my error?
import javax.enterprise.context.RequestScoped;
import javax.websocket.server.PathParam;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
#Path("/feed")
#RequestScoped
public class FeedHandler {
#POST
#Path("/send-batch/{batchid}")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response sendBatch(#PathParam("batchid") String batchid) {
}
The problem is your import.
You are using
import javax.websocket.server.PathParam;
but you should be using
import javax.ws.rs.PathParam;